Search code examples
androidandroid-fragmentsandroid-viewpagerfragment-lifecycle

Where to restore fragment state that is inside ViewPager


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?


Solution

  • So I found where the problem was. Just posting the answer here. So when the screen is rotated, although I am updating the data source, I have not reattached the listview with the updated adapter. So I just did that and it works.

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

    Just posted the answer if anyone made the same mistake and was wondering what went wrong.