【问题标题】:Fragment re-created when change tab with ViewPager使用 ViewPager 更改选项卡时重新创建片段
【发布时间】:2018-08-07 01:52:33
【问题描述】:

我有一个ViewPager,有 4 个标签。

我正在使用扩展 FragmentPagerAdapter 的自定义适配器。

问题是,当我更改选项卡时,第一个 Fragment 会再次创建,尽管它不是当前可见的。 此外,这仅在第四次更改选项卡后才会发生。例如。调用来自 tab1 的 tab1 -> tab2 -> tab3=> onStop。 -> tab2 => 来自 tab1 的 onCreateView 被调用(onAttach 未被调用)。

我想避免这种情况。我需要所有选项卡始终保持其状态,即使它们当前未显示。 我该怎么做?

【问题讨论】:

    标签: android android-fragments android-viewpager


    【解决方案1】:

    就像使用来自ViewPager 的方法setOffscreenPageLimit() 一样简单。

    更多信息:http://developer.android.com/reference/android/support/v4/view/ViewPager.html#setOffscreenPageLimit(int)

    【讨论】:

    • 感谢 mahn,我的代码终于可以正常工作了!我正在寻找保存的实例,但是这 1 个 LOC 使我的代码工作 xD
    • 当设置为 0 时,它似乎仍会加载侧面片段。. 最小值是 1 吗?编辑:原来是的,最小值是 1
    【解决方案2】:

    Viewpager 有一个名为 setOffScreenPageLimit 的公共方法,它指示在空闲状态下将保留到视图层次结构中当前页面任一侧的页面数。

    活动:

        private SectionsPagerAdapter mSectionsPagerAdapter;
        private ViewPager mViewPager;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
    
    ...
    
            mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
    
            mViewPager = findViewById(R.id.container);
            mViewPager.setOffscreenPageLimit(3);  // change your number here
            mViewPager.setAdapter(mSectionsPagerAdapter);
    

    【讨论】:

      【解决方案3】:

      实例化片段时,调用setRetainInstance(true)。这将保留片段的实例状态。 onCreateView 仍将被调用,您需要确保重新使用保存的状态并仅渲染视图而无需再次加载任何数据,例如通过使用boolean 来表示您的片段是否已经初始化。

      你会做这样的事情:

      public static class MyAdapter extends FragmentPagerAdapter {
             @Override
             public Fragment getItem(int position) {
                     MyFragment myFragment = new MyFragment();
                     myFragment.setRetainInstance(true);
                     return myFragment;
             }
      }
      
      class MyFragment extends Fragment {
             .
             .
             .
      
             boolean initialized = false;
             ArrayList<MyData> myData = null;
      
             void onCreate(...) {
                     if (initialized) {
                             renderViews();
                     } else {
                             initialized = true;
                             loadData();
                             renderViews();
                     }
             }
      }
      

      您不需要实现onSaveInstanceState()。会自动处理。

      【讨论】:

      • 我不明白这种行为。。如果它甚至不是显示的,为什么在停止后又重新创建?不过,我正在尝试遵循您的方法,但我无法弄清楚如何保存状态。我在FragmentonCreateView() 中添加了setRetainInstance(true),但从未调用过onSaveInstanceState()
      • 再次调用它是因为它在当前视图的左侧和右侧创建了一个片段,以便它可以用滑动动画显示它。有关详细信息,请参阅我的编辑。
      • 现在更清楚了,但我对onCreate() 中的视图没有做任何事情,但在onCreateView() 中需要返回一个View,必须对其进行修改以匹配以前的状态。事实上,当我使用 myFragment.setRetainInstance(true); 时,onCreateView()onCreate() 不会在以前被调用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-04
      • 2021-12-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多