Where to restore fragment state that is inside ViewPager

Gaurav Pandey picture Gaurav Pandey · Jun 23, 2015 · Viewed 14.4k times · Source

Short Version:

I have an Activity that has a ViewPager. The ViewPager has three fragments inside it. I am storing the data inside the fragments by implementing Parcelable and storing it inside the bundle.

Now the question is where do I restore the data. I am confused because (from what I know) the ViewPager is creating a new instance of the fragment each time I rotate the screen. (A new activity is created -> new ViewPager -> new Fragment). Please do correct me if I am wrong.

Long version:

My ViewPager inside MainActivity

ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setAdapter(new ForecastFragmentPageAdapter(getSupportFragmentManager(),
            ForecastActivity.this));
viewPager.setOffscreenPageLimit(2);

My FragmentPagerAdapter

 @Override
public Fragment getItem(int position) {
    if (position == 0) {
        return new NowForecastFragment();
    } else if (position == 1) {
        return new HourlyForecastFragment();
    } else {
        return new DailyForecastFragment();
    }
}

Saving state in one of my fragments

    public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    // save data source
    if (nowDataList != null) {
        outState.putParcelableArrayList("savedNowDataList", nowDataList);
    }
}

Thanks in advance!

UPDATE:

According to other solutions posted to similar problems, I also added setRetainInstance(true); in the onCreateView of my fragment. And this is how I am saving and restoring state:

    @Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    // save data source
    if (nowDataList != null) {
        Log.v("---------------->","saved!");
        outState.putParcelableArrayList("savedNowDataList", nowDataList);
    }
}

and restoring in onCreateView

 if(savedInstanceState!=null) {
            Log.v("---------------->","restored!");
            nowDataList = savedInstanceState.getParcelableArrayList("savedNowDataList");
            nowForecastAdapter.notifyDataSetChanged();
        }

I see both the logs being triggered. Why is the data not being restored?

Answer

kris larson picture kris larson · Jun 24, 2015

When the ViewPager saves its state, it calls saveState() on its adapter. Similarly, when the ViewPager goes to restore its state, it calls restoreState on the adapter.

You could implement these methods, but that's already been done. Simply extend FragmentStatePagerAdapter instead of FragmentPagerAdapter and you get those method implementations for free.

If you extend FragmentStatePagerAdapter then implement onSaveInstanceState() and restore the state in onCreateView() for your Fragment classes, all should work as you expect.