android - 在屏幕旋转时在 ViewPager 中保存 fragment 状态

标签 android android-viewpager fragment

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

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

是否可以以及如何在 ViewPager 中保存 fragment 状态?

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

Activity

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 和重新创建 Activity 时会发生什么:

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

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

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

最佳答案

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

还有setRetainInstance()在 fragment 上,但它总是给我带来一些奇怪的行为,所以我没有使用它。

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

关于android - 在屏幕旋转时在 ViewPager 中保存 fragment 状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32986615/

相关文章:

android 应用程序在运行时添加内容

ViewPager 的 Android 事件监听器数据绑定(bind)

android - 并非 ViewPager 的 fragment 中的所有 View 都会更新

android - 为不同的方向使用不同的布局时,在方向更改时保存 fragment 状态

android - 由 java.lang.IllegalStateException : Can't create ViewModelProvider for detached fragment 引起

android - Android fragment 中的谷歌地图

java - 迭代器 isEmpty() 调用导致 noSuchElement 异常?

java - 如何在 Android Studio 上向我的项目添加库?

android - 在 getrrsetbyname.c 中交叉编译适用于 Android 的 OpenSSH 失败

android - 如何将 float 操作按钮拖到 View 寻呼机上