Alex
Alex

Reputation: 1103

How to deal with FragmentPagerAdapter reusing Fragments?

So, I'm trying to use a ViewPager from Android's support v4 library, but there's some serious issues with how it (or FragmentPagerAdapter) deals with Fragments. For instance, I subclassed FragmentPagerAdapter to do the following:

public class MyPagerAdapter extends FragmentPagerAdapter
{
private ArrayList<Fragment> fragments = null;
private ArrayList<Data> data = null;

public MyPagerAdapter(FragmentManager fragmentManager, ArrayList<Data> data)
{
    super(fragmentManager);

    this.data = data;

    fragments = new ArrayList<Fragment>();

    for(Data datum : data)
    {
        MyDataFragment fragment = new MyDataFragment();
        fragment.setData(datum);
        fragments.add(fragment);
    }
}

@Override
public Fragment getItem(int i)
{
    return fragments.get(i);
}

@Override
public int getCount()
{
    return fragments.size();
}
}

Now, I thought this would be sufficient, and that I could go on and implement MyDataFragment using the onCreateView method that Fragments typically implement. But I ran into an interesting problem. When I would navigate away from the Activity, and then back to it, the ViewPager would appear blank. Somehow, it was reusing Fragments by calling findFragmentByTag, then simply not even calling getItem, etc. What's worse, the Fragment would get no onCreateView event. So I figured I could utilize the ViewPager's Fragment caching by moving my onCreateView code, which primarily grabs references to the various Views the fragment inflates, to onAttach. The only problem is, that during onAttach, MyDataFragment's getView method always returns null. All of the examples for Fragments online describe that onCreateView should have all of your view setup code. Ok, fine. But then, when I create a method like MyDataFragment.setSomeField(String value), I need to use a reference to a TextView. Since onCreateView doesn't always get called (like, when Fragments are magically recycled by FragmentPagerAdapter, for instance), it's better to grab that reference in onAttach. However, during onAttach, the root view for the Fragment is still null (probably because onCreateView wasn't called in the first place)! No additional events happen after that (with the exception of onActivityCreated, which has nothing to do with the Fragment itself), so there's no place to do setup code. How is this supposed to work? Am I missing something important here, or was the Fragment system designed by a monkey?

Upvotes: 4

Views: 2004

Answers (1)

TisSarah
TisSarah

Reputation: 101

I'm not sure that this is the right use case for a FragmentPagerAdapter (it sounds more like something you'd want to do with a ListAdapter).

From the FragmentPagerAdapter docs:

Implementation of PagerAdapter that represents each page as a Fragment that is persistently kept in the fragment manager as long as the user can return to the page.

This version of the pager is best for use when there are a handful of typically more static fragments to be paged through, such as a set of tabs. The fragment of each page the user visits will be kept in memory, though its view hierarchy may be destroyed when not visible. This can result in using a significant amount of memory since fragment instances can hold on to an arbitrary amount of state. For larger sets of pages, consider FragmentStatePagerAdapter.

I'd consider switching to the FragmentStatePagerAdapter or perhaps a ListAdapter. If you want the createView to be called it will have to be recreated each time (destroy the old fragment and create new ones), but again I don't think that's quite what you want.

Upvotes: 1

Related Questions