3

I'm using a ViewPager and displaying a lot of different Fragments inside it, not only in content but they use different classes as well. The list to be displayed should be changed dynamically and even though I manage to swap items around and add new ones to the adapter(and calling notifyDataSetChanged), if I try changing the next item it will still slide to it when using mPager.setCurrentItem(mPager.getCurrentItem() + 1);

I am just adding a new Fragment between the current item and the current next one, it is displayed correctly in the adapter but as the next one was already preloaded then getItem in the adapter is not even called.

Is there another method "stronger" than notifyDataSetChanged that tells my ViewPager that it should get the next item again?


CODE SAMPLES:

The add and get item methods inside my FragmentPagerAdapter(only samples, not the actual code)

public void add(@NonNull Integer fragmentIndex) { mFragmentOrder.add(fragmentIndex); notifyDataSetChanged(); } @Override public Fragment getItem(int position) { int selectedFragment = mFragmentOrder(position); Fragment fragment; switch (selectedFragment) { case 1: fragment = new FragmentA(); break; case 2: fragment = new FragmentB(); break; case 3: fragment = new FragmentC(); break; default: fragment = new FragmentD(); break; } return fragment; } 

This is the function used to go to the next item(I don't allow swiping)

public void goToNext() { mPager.setCurrentItem(mPager.getCurrentItem() + 1); } 

EDITS:

Edit 1: I had already tried using a FragmentStatePagerAdapter instead and setting the OffscreenPageLimit to 0, but to no avail.

Edit 2: [Solution] Using a FragmentStatePagerAdapter AND overwriting the getItemPosition function to return POSITION_NONE or the index in the appropriate cases solved the problem. For some reason even after implementing the right version of this function the normal FragmentPagerAdapter kept delivering the wrong Fragment.

2
  • developer.android.com/reference/android/support/v4/app/… Commented Sep 13, 2017 at 17:13
  • I had already tried with the FragmentStateAdapter as well, it wouldn't fix the problem anyway. As I said, the ViewPager is not requerying the adapter for the new "next" slide, it just shows the one already preloaded. Trying to set the off page limit does nothing as well. Commented Sep 13, 2017 at 20:43

1 Answer 1

1

By default, FragmentPagerAdapter assumes that the number and positions of its items remain fixed. Therefore, if you want to introduce for dynamism, you have to provide for it yourself by implementing the getItemPosition(Object object) method in the inherited adapter class. A very basic (but unefficient) implementation would be this:

@Override public int getItemPosition(Object object) { return POSITION_NONE; } 

Every time the parent view is determining whether the position of one of its child views (items) has changed, this code will force the fragment to be recreated. If you want to avoid the recreation when unnecessary, you have to include some logic in the method. Something like this:

@Override public int getItemPosition (Object object) { if (fragmentOrder.indexOf(object) == -1) { return POSITION_NONE; } else { return index; } } 

Finally, pay attention to possible memory leaks by adding an onDestroyView method to your fragments and nullifying the views you are using.

Here is a good discussion of these issues with the two PagerAdapters.

Sign up to request clarification or add additional context in comments.

1 Comment

Combining your solution with a FragmentStateAdapter did the trick. Thanks, and the article you linked is useful as well.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.