在哪里恢复 ViewPager 内部的片段状态
Where to restore fragment state that is inside ViewPager
短版:
我有一个带有 ViewPager 的 Activity。 ViewPager 内部包含三个片段。我通过实施 Parcelable 并将其存储在包中来将数据存储在片段中。
现在的问题是我在哪里恢复数据。我很困惑,因为(据我所知)每次我旋转屏幕时 ViewPager 都会创建一个新的片段实例。 (创建了一个新的 activity -> new ViewPager -> new Fragment)。如有不妥请指正
长版:
Main 中的我的 ViewPagerActivity
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setAdapter(new ForecastFragmentPageAdapter(getSupportFragmentManager(),
ForecastActivity.this));
viewPager.setOffscreenPageLimit(2);
我的 FragmentPagerAdapter
@Override
public Fragment getItem(int position) {
if (position == 0) {
return new NowForecastFragment();
} else if (position == 1) {
return new HourlyForecastFragment();
} else {
return new DailyForecastFragment();
}
}
在我的一个片段中保存状态
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// save data source
if (nowDataList != null) {
outState.putParcelableArrayList("savedNowDataList", nowDataList);
}
}
提前致谢!
更新:
根据针对类似问题发布的其他解决方案,我还在片段的 onCreateView 中添加了 setRetainInstance(true); 。这就是我保存和恢复状态的方式:
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// save data source
if (nowDataList != null) {
Log.v("---------------->","saved!");
outState.putParcelableArrayList("savedNowDataList", nowDataList);
}
}
并在 onCreateView 中恢复
if(savedInstanceState!=null) {
Log.v("---------------->","restored!");
nowDataList = savedInstanceState.getParcelableArrayList("savedNowDataList");
nowForecastAdapter.notifyDataSetChanged();
}
我看到两个日志都被触发了。为什么数据没有恢复?
当 ViewPager
保存其状态时,它会在其适配器上调用 saveState()
。同样,当 ViewPager
恢复其状态时,它会在适配器上调用 restoreState
。
您可以实施这些方法,但这已经完成了。只需扩展 FragmentStatePagerAdapter
而不是 FragmentPagerAdapter
,您就可以免费获得这些方法实现。
如果您扩展 FragmentStatePagerAdapter
然后实施 onSaveInstanceState()
并为您的 Fragment
类 恢复 onCreateView()
中的状态,一切都应该如您所愿。
所以我找到了问题所在。只是在这里发布答案。所以当屏幕旋转时,虽然我正在更新数据源,但我没有用更新的适配器重新附加列表视图。所以我就这样做了,它起作用了。
if(savedInstanceState!=null) {
Log.v("---------------->","restored!");
nowDataList = savedInstanceState.getParcelableArrayList("savedNowDataList");
nowForecastAdapter = new NowForecastAdapter(this, nowDataList);
lvNowList.setAdapter(nowForecastAdapter);
nowForecastAdapter.notifyDataSetChanged();
}
如果有人犯了同样的错误并且想知道哪里出了问题,请发布答案。
短版:
我有一个带有 ViewPager 的 Activity。 ViewPager 内部包含三个片段。我通过实施 Parcelable 并将其存储在包中来将数据存储在片段中。
现在的问题是我在哪里恢复数据。我很困惑,因为(据我所知)每次我旋转屏幕时 ViewPager 都会创建一个新的片段实例。 (创建了一个新的 activity -> new ViewPager -> new Fragment)。如有不妥请指正
长版:
Main 中的我的 ViewPagerActivity
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setAdapter(new ForecastFragmentPageAdapter(getSupportFragmentManager(),
ForecastActivity.this));
viewPager.setOffscreenPageLimit(2);
我的 FragmentPagerAdapter
@Override
public Fragment getItem(int position) {
if (position == 0) {
return new NowForecastFragment();
} else if (position == 1) {
return new HourlyForecastFragment();
} else {
return new DailyForecastFragment();
}
}
在我的一个片段中保存状态
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// save data source
if (nowDataList != null) {
outState.putParcelableArrayList("savedNowDataList", nowDataList);
}
}
提前致谢!
更新:
根据针对类似问题发布的其他解决方案,我还在片段的 onCreateView 中添加了 setRetainInstance(true); 。这就是我保存和恢复状态的方式:
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// save data source
if (nowDataList != null) {
Log.v("---------------->","saved!");
outState.putParcelableArrayList("savedNowDataList", nowDataList);
}
}
并在 onCreateView 中恢复
if(savedInstanceState!=null) {
Log.v("---------------->","restored!");
nowDataList = savedInstanceState.getParcelableArrayList("savedNowDataList");
nowForecastAdapter.notifyDataSetChanged();
}
我看到两个日志都被触发了。为什么数据没有恢复?
当 ViewPager
保存其状态时,它会在其适配器上调用 saveState()
。同样,当 ViewPager
恢复其状态时,它会在适配器上调用 restoreState
。
您可以实施这些方法,但这已经完成了。只需扩展 FragmentStatePagerAdapter
而不是 FragmentPagerAdapter
,您就可以免费获得这些方法实现。
如果您扩展 FragmentStatePagerAdapter
然后实施 onSaveInstanceState()
并为您的 Fragment
类 恢复 onCreateView()
中的状态,一切都应该如您所愿。
所以我找到了问题所在。只是在这里发布答案。所以当屏幕旋转时,虽然我正在更新数据源,但我没有用更新的适配器重新附加列表视图。所以我就这样做了,它起作用了。
if(savedInstanceState!=null) {
Log.v("---------------->","restored!");
nowDataList = savedInstanceState.getParcelableArrayList("savedNowDataList");
nowForecastAdapter = new NowForecastAdapter(this, nowDataList);
lvNowList.setAdapter(nowForecastAdapter);
nowForecastAdapter.notifyDataSetChanged();
}
如果有人犯了同样的错误并且想知道哪里出了问题,请发布答案。