Search code examples
javaandroidandroid-fragmentsandroid-viewpagerfragmentstatepageradapter

FragmentStatePagerAdapter does not handle changes


I am having a problem managing a changing list of item using the FragmentStatePagerAdapter. Please check source here.

The problem is that when the underlying list changes, and I call notifyDataSetChanged, the adapter does not rebuild it's internal list of fragments. Referring to the code in instantiateItem:

@Override
public Object instantiateItem(ViewGroup container, int position) {
    // If we already have this item instantiated, there is nothing
    // to do.  This can happen when we are restoring the entire pager
    // from its saved state, where the fragment manager has already
    // taken care of restoring the fragments we previously had instantiated.
    if (mFragments.size() > position) {
        Fragment f = mFragments.get(position);
        if (f != null) {
            return f;
        }
    }

I believe the code in this comment is wrong! If I delete the item at position 0 in the list, and I call notifyDataSetChanged, then the fragment at position 0 should be deleted. However the adapter has never updated the position of fragments in its own private list. Therefore it still shows the old, deleted, data.

I found this answer but it is a hack that relies on getItemPosition being called and then forcing the fragment to update it's views.

How is it possible to manage fragments in a changing list?


Solution

  • Per the ViewPager.dataSetChanged() source, it uses PagerAdapter.getItemPosition() to determine the new position of a item after a data change. By default, getItemPosition() always returns POSITION_UNCHANGED, meaning it never destroys and recreates items it has already created.

    Override getItemPosition() to return the correct value if you want to update Fragments that already exist in response to a notifyDataSetChanged() call. For example, always returning POSITION_NONE will always destroy every Fragment and recreate them from scratch (which, in most cases, is more work than needs to be done if items are just reordering).