[英]How to Restore ViewPager from savedInstanceState
所以我有一个我似乎无法解决的问题。 我在其中一项活动中有一个ViewPager,比如MainActivity 。 当活动在后台被杀死时,我正在实现保存和检索实例状态所需的所有方法。 但是当活动尝试恢复其状态时,片段将被恢复,但它们不会附加到viewpager,所以我得到的只是一个白色屏幕。
这是相关代码:
MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//..
if (savedInstanceState==null) {
setupViewPager();
}
}
private void setupViewPager() {
mAdapter = new ViewPagerAdapter(getSupportFragmentManager());
mAdapter.addFrag(FirstFragment.newInstance(mFeedItem), "INFO");
//Note: mFeedItem is obtained from the intent and I have verified
// that it is properly restored.
mAdapter.addFrag(SecondFragment.newInstance(mFeedItem), "SERVICES");
mViewPager.setAdapter(mAdapter);
mTabLayout.setupWithViewPager(mViewPager);
}
ViewPagerAdapter.java
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFrag(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
FirstFragment.java
public static FirstFragment newInstance(Workshop item) {
FirstFragment f = new FirstFragment();
f.mItem = item;
return f;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("feed_item",Workshop.packToGson(mItem));
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_item_detail_info, container, false);
if (savedInstanceState!=null) {
mItem = Workshop.extractGson(savedInstanceState.getString("feed_item"));
}
return v;
}
因此,如果我导航到另一个活动,然后MainActivity
在后台被杀死(我使用Do not Keep Activities设置来测试它),会发生这种情况:
1)活动正确恢复,没有问题。
2)调用片段的onCreateView
,且savedInstanceState
保持不变。
3)但是,我的Activity中的ViewPager和Adapter是null
。 片段似乎没有附加到适配器/ viewpager。
那我在这里错过了什么? 我应该做些什么来正确恢复碎片吗?
我可以通过在MainActivity
替换它来快速解决问题:
if (savedInstanceState==null) {
setupViewPager();
}
只需setupViewPager();
,以便创建新的适配器和片段,无论它是第一次还原还是启动。 但这带来了重置片段状态的缺点。 此外,当我这样做时,我发现每个片段有两个实例,一个是恢复的,另一个是新实例,只实际显示了新实例。 所以我不相信这是最好的方法。
通过销毁Activity
您还会销毁每个实例字段。 所以你必须重新实例化ViewPager
和Adapter
。 您必须记住两种情况。
FragmentStatePagerAdapter
保存/恢复Fragments
与FragmentManager
Fragments
内Fragment
第一点是每个Fragment
有两个实例的原因。 为了解决这个问题,您可以通过其ID获取存储的Fragment。 看到这个 grepcode FragmentPagerAdapter
(同样适用于StateAdapter
)
private static String makeFragmentName(int viewId, int index) {
return "android:switcher:" + viewId + ":" + index;
}
而不是每次都在setupViewPager
中实例化Fragment
- 你首先从FragmentManager
获取它,例如
mAdapter = new ViewPagerAdapter(getSupportFragmentManager());
int fragmentCount = 2; // save value if it's a arbitrary list of fragments
for (int index = 0; i < fragmentCount; i++) {
FirstFragment firstFragment = (FirstFragment) getSupportFragmentManager().findFragmentByTag(makeFragmentName(R.id.view_pager, index));
if (firstFragment == null) {
firstFragment = FirstFragment.newInstance(mFeedItem);
}
mAdapter.addFrag(firstFragment, "someTitle");
}
以上是如何从FragmentManager
恢复以前保存的Fragments
的示例。 您可能需要调整具有不同类型BaseFragments
,依此类推。 此外,您可能希望保存Fragment
标题名称和总计数以还原它们。
第二点是你必须从Fragment
本身恢复当前的Fragment
状态。 为此,您的Fragment
具有生命周期方法。 请参阅此SO主题关于一劳永逸,如何在后端堆栈中正确保存Fragments的实例状态?
FragmentStatePagerAdapter具有saveState()和restoreState()方法来保存和恢复它的状态。
saveState:保存与此适配器关联的任何实例状态及其在需要重建当前UI状态时应恢复的页面。
因此,似乎可以使用这些方法来存档您的目标。 对不起,我现在没有编译器,所以我无法测试下面的代码。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
setupViewPager(savedInstanceState);
}
}
private void setupViewPager(Bundle savedInstanceState) {
mAdapter = new ViewPagerAdapter(getSupportFragmentManager());
if (savedInstanceState != null) {
Parcelable parcelable = savedInstanceState.getParcelable("Adapter");
mAdapter.restoreState(parcelable, getClassLoader());
} else {
mAdapter.addFrag(FirstFragment.newInstance(mFeedItem), "INFO");
//Note: mFeedItem is obtained from the intent and I have verified
// that it is properly restored.
mAdapter.addFrag(SecondFragment.newInstance(mFeedItem), "SERVICES");
}
mViewPager.setAdapter(mAdapter);
mTabLayout.setupWithViewPager(mViewPager);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Parcelable parcelable = mAdapter.saveState();
outState.putParcelable("Adapter", parcelable);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.