【问题标题】:Save fragments state in ViewPager on screen rotation在屏幕旋转时在 ViewPager 中保存片段状态
【发布时间】:2016-01-04 08:29:04
【问题描述】:

我有带有 2 个片段的 TabLayout 和 ViewPager,每个片段都是一个从 firebase 加载数据的 recyclerView。

一切正常。但是当我改变屏幕方向时,ViewPager 会重新创建每个片段,片段会再次加载数据。

是否有可能以及如何在 ViewPager 中保存片段状态?

但我不想重写 onSaveInstanceState 方法来创建数据集然后恢复它。在检查现有片段时,我想要按标签查找片段之类的东西。

活动

public class MainActivity extends BaseBroadcastActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    mViewPager = (ViewPager) findViewById(R.id.viewpager);
    setupViewPager(mViewPager);

    TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(mViewPager);
}

private void setupViewPager(ViewPager viewPager) {
    Adapter adapter = new Adapter(getSupportFragmentManager());
    adapter.addFragment(MainListFragment.newInstance(connected, "Notices"), "Notices");
    adapter.addFragment(MainListFragment.newInstance(connected, "Posts"), "Posts");
    viewPager.setAdapter(adapter);
}

static class Adapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragments = new ArrayList<>();
    private final List<String> mFragmentTitles = new ArrayList<>();

    public Adapter(FragmentManager fm) {
        super(fm);
    }

    public void addFragment(Fragment fragment, String title) {
        mFragments.add(fragment);
        mFragmentTitles.add(title);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragments.get(position);
    }

    @Override
    public int getCount() {
        return mFragments.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitles.get(position);
    }
}

在 MainListFragment 中,我只创建 recyclerView 并从 firebase 加载数据。

谢谢!

编辑

感谢您的回复!

我发现我的错误。当我们第一次创建 FragmentPageAdapter 和重新创建活动时会发生什么:

  1. FragmentPageAdapter 调用 instantiateItem 方法,它通过标签查找片段,如果片段存在适配器使用它,但如果片段不存在,则适配器调用 getItem 方法并创建片段。

  2. 在我的情况下,片段没有重新创建,但是数据正在刷新,因为我在片段的 onCreateView 方法中刷新了它们,但现在我正在编辑 onCreateView:

    if (savedInstanceState == null) { 检索数据(); }

【问题讨论】:

    标签: android android-viewpager fragment


    【解决方案1】:

    应该以始终在getItem() 中返回新实例的方式完成。我也宁愿使用FragmentStatePagerAdapter,尤其是当您有更多页面时。 您还需要在onSaveInstanceState() 中保存所有可能丢失的内部状态。如果您不想重新加载,则需要保存数据。如果你在 POJO 中有一些数据,你可以给它们添加 Serializable 接口,以便轻松地将它们序列化为 bundle。

    fragment 上也有setRetainInstance(),但它总是对我造成一些奇怪的行为,所以我没有使用它。

    static class Adapter extends FragmentStatePagerAdapter {
    
        public Adapter(FragmentManager fm) {
            super(fm);
        }
    
        @Override
        public Fragment getItem(int position) {
            Fragment fragment=null;
            switch (position) {
                case 0: fragment=MainListFragment.newInstance(mConnected, "Notices"); //don't forget to save mConnected in savedInstanceState
                case 1: fragment=MainListFragment.newInstance(mConnected, "Posts");
            }
            return fragment;
        }
    
        @Override
        public int getCount() {
            return 2;
        }
    
        @Override
        public CharSequence getPageTitle(int position) {
            String title="";
            switch (position) {
                case 0: title="Notices";
                case 1: title="Posts";
            }
            return title;
        }
    

    【讨论】:

    • 谢谢,但我知道我可以将下载的数据保存在片段中,然后再恢复。如果在片段管理器堆栈中找到现有片段并在没有任何额外代码的情况下恢复它,我会很有趣。我认为这是可能的,但我不知道如何。
    • 有一种方法可以从寻呼机中获取片段。但它仅适用于FragmentPagerAdapter。 stackoverflow.com/questions/14035090/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多