【问题标题】:Where to restore fragment state that is inside ViewPager在哪里恢复 ViewPager 中的片段状态
【发布时间】:2015-06-23 21:38:04
【问题描述】:

短版:

我有一个具有 ViewPager 的 Activity。 ViewPager 里面有三个片段。我通过实现 Parcelable 并将数据存储在包中来将数据存储在片段中。

现在的问题是我在哪里恢复数据。我很困惑,因为(据我所知)每次旋转屏幕时,ViewPager 都会创建片段的新实例。 (创建了一个新活动 -> 新 ViewPager -> 新片段)。如果我错了,请纠正我。

加长版:

我在 MainActivity 中的 ViewPager

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();
        }

我看到两个日志都被触发了。为什么数据没有恢复?

【问题讨论】:

  • 我想这会对你有所帮助stackoverflow.com/questions/7951730/…
  • 虽然解决方案为我清除了很多东西,但我并没有从活动中初始化我的片段。我的 FragmentPageAdapter 正在这样做。所以,我不确定如何在我的活动中保存和恢复我的片段。
  • 嗨伙计,只需在清单文件中设置 configchanges = screensize ,它不会重新加载片段并保留当前状态。希望有帮助:)

标签: android android-fragments android-viewpager fragment-lifecycle


【解决方案1】:

当ViewPager 保存其状态时,它会在其适配器上调用saveState()。同样,当ViewPager 恢复其状态时,它会调用适配器上的restoreState。

您可以实现这些方法,但这已经完成了。只需扩展 FragmentStatePagerAdapter 而不是 FragmentPagerAdapter 即可免费获得这些方法实现。

如果您扩展 FragmentStatePagerAdapter 然后实现 onSaveInstanceState() 并为您的 Fragment 类恢复 onCreateView() 中的状态,所有这些都应该按您的预期工作。

【讨论】:

  • 一个带代码的例子在这里会非常有帮助:-)
  • 这在类似情况下很有帮助。它应该是公认的答案。
  • 恢复是自动完成的,但是在片段中查看寻呼机呢,我想获取适配器的旧引用,因为它是自动处理的。
  • FragmentStatePagerAdapter 的文档有一个完整的工作示例:developer.android.com/reference/android/support/v4/app/…
  • 但是没有保存和恢复状态的例子
【解决方案2】:

所以我找到了问题所在。只是在这里发布答案。所以当屏幕旋转时,虽然我正在更新数据源,但我并没有用更新的适配器重新附加列表视图。所以我就这么做了,它确实有效。

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

如果有人犯了同样的错误并且想知道出了什么问题,请发布答案。

【讨论】:

  • 如果nowDataList是适配器的数据,最好用Loader代替。列表可能很长,以至于无法很好地放入包中,并且可能导致性能问题。
  • @GauravPandey 这里的问题是你如何恢复视图寻呼机的片段?如果您在重新创建活动时创建片段的新实例,则您有两个片段实例,一个是新创建的片段,第二个是恢复的旧片段。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-31
相关资源
最近更新 更多