简体   繁体   English

何处恢复ViewPager内部的片段状态

[英]Where to restore fragment state that is inside ViewPager

Short Version: 精简版:

I have an Activity that has a ViewPager. 我有一个具有ViewPager的Activity。 The ViewPager has three fragments inside it. ViewPager里面有三个片段。 I am storing the data inside the fragments by implementing Parcelable and storing it inside the bundle. 我通过实现Parcelable并将其存储在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. 我很困惑,因为(据我所知)ViewPager每次旋转屏幕时都会创建片段的新实例。 (A new activity is created -> new ViewPager -> new Fragment). (创建一个新活动 - >新的ViewPager - > new Fragment)。 Please do correct me if I am wrong. 如果我错了,请纠正我。

Long version: 长版:

My ViewPager inside MainActivity 我在MainActivity中的ViewPager

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

My FragmentPagerAdapter 我的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); 根据发布到类似问题的其他解决方案,我还添加了setRetainInstance(true); in the onCreateView of my fragment. 在我片段的onCreateView中。 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 并在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? 为什么数据没有恢复?

When the ViewPager saves its state, it calls saveState() on its adapter. ViewPager保存其状态时,它会在其适配器上调用saveState() Similarly, when the ViewPager goes to restore its state, it calls restoreState on the adapter. 同样,当ViewPager恢复其状态时,它会调用适配器上的restoreState

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. 只需扩展FragmentStatePagerAdapter而不是FragmentPagerAdapter ,您就可以免费获得这些方法实现。

If you extend FragmentStatePagerAdapter then implement onSaveInstanceState() and restore the state in onCreateView() for your Fragment classes, all should work as you expect. 如果扩展FragmentStatePagerAdapter然后实现onSaveInstanceState()并在onCreateView()恢复Fragment类的状态,则所有这些都应该按预期工作。

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. 因此,当屏幕旋转时,虽然我正在更新数据源,但我没有使用更新的适配器重新附加listview。 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. 刚发布答案,如果有人犯了同样的错误,并想知道出了什么问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM