Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android FragmentStatePagerAdapter

Tags:

I'm working with a FragmentStatePagerAdapter using this example.

The MyAdapter class is implemented as follows:

public static class MyAdapter extends FragmentStatePagerAdapter {         public MyAdapter(FragmentManager fm) {             super(fm);         }          @Override         public int getCount() {             return NUM_ITEMS;         }          @Override         public Fragment getItem(int position) {             return ArrayListFragment.newInstance(position);         }     } 

The ListFragment class includes the following method to create a new instance:

    /**      * Create a new instance of CountingFragment, providing "num"      * as an argument.      */     static ArrayListFragment newInstance(int num) {         ArrayListFragment f = new ArrayListFragment();          // Supply num input as an argument.         Bundle args = new Bundle();         args.putInt("num", num);         f.setArguments(args);          return f;     } 

When I create a new fragment state pager adapter in my activity, getItem is called, which in turn calls the newInstance method in the ListFragment class. This is great when I want to create a new fragment.

But it's not clear to me how to modify getItem (if even needed) to get the fragment object when it already exists and the user pages from, for example, page 2 to page 1. I'd like my Activity to retrieve that existing, previously created fragment so that it can run an inner class AsyncMethod, which resides in the fragment class.

like image 437
mraviator Avatar asked May 18 '12 16:05

mraviator


People also ask

What is the difference between FragmentPagerAdapter vs FragmentStatePagerAdapter?

FragmentPagerAdapter is used exactly like FragmentStatePagerAdapter . It only differs in how it unloads your fragments when they are no longer needed (Figure 11.4). With FragmentStatePagerAdapter , your unneeded fragment is destroyed.

What can I use instead of FragmentPagerAdapter?

ViewPager2 and use androidx. viewpager2. adapter. FragmentStateAdapter instead.

How do I update my Android ViewPager adapter?

Firstly set viewpager adapter to null then recreate the adapter and set i to it to viewpager. Show activity on this post. Define which message which is needed to update.


2 Answers

I think the solution is much simpler than the answers provided.

If you take a look at the source of FragmentStatePagerAdapter.instantiateItem(), you'll notice that instantiateItem() handles this logic for you, and thus your implementation of getItem() should always return a new instance.

So in order to return an existing Fragment, simply do (assuming you're calling from ViewPager):

Fragment f = (Fragment) getAdapter().instantiateItem(this, getCurrentItem()); 
like image 50
imiric Avatar answered Sep 21 '22 18:09

imiric


While @imiric's solution is very concise, it still bothers me that it requires knowledge of the implementation of the class. My solution involves adding the following to your adapter, which should behave nicely with a FragmentStatePagerAdapter possibly destroying fragments:

    private SparseArray<WeakReference<Fragment>> mFragments = new SparseArray<>();      @Override     public Object instantiateItem(ViewGroup container, int position) {         Fragment f = (Fragment) super.instantiateItem(container, position);         mFragments.put(position, new WeakReference<>(f));  // Remember what fragment was in position         return f;     }      @Override     public void destroyItem(ViewGroup container, int position, Object object) {         super.destroyItem(container, position, object);         mFragments.remove(position);     }      public Fragment getFragment(int position) {         WeakReference<Fragment> ref = mFragments.get(position);         Fragment f = ref != null ? ref.get() : null;         if (f == null) {             Log.d(TAG, "fragment for " + position + " is null!");         }         return f;     } 
like image 33
qix Avatar answered Sep 18 '22 18:09

qix