FragmentStatePagerAdapter 视图分页器片段在活动重新创建后不显示

Posted

技术标签:

【中文标题】FragmentStatePagerAdapter 视图分页器片段在活动重新创建后不显示【英文标题】:FragmentStatePagerAdapter view pager fragments not showing after activity recreate 【发布时间】:2018-06-20 18:28:12 【问题描述】:

当我的Activity 通过方向更改重新创建或如果在开发人员设置中打开“不保留活动”时,我的ViewPager 具有 FragmentStatePagerAdapter 不会重新创建片段。

这是活动onCreate 方法:

@Override
  protected void onCreate(@Nullable Bundle savedInstanceState) 
    androidInjection.inject(this);
    super.onCreate(savedInstanceState);
    ButterKnife.bind(this);
    pagerAdapter = new CustomPagerAdapter(getSupportFragmentManager());
    viewPager.setAdapter(pagerAdapter);
    viewPager.addOnPageChangeListener(this);

    presenter.onCreate();
  

这是 FragmentStatePager:

public class CustomPagerAdapter extends FragmentStatePagerAdapter 

  private List<Fragment> fragments = new ArrayList<>();

  public MyFoodaPagerAdapter(FragmentManager fm) 
    super(fm);
  

  public void init(List<Fragment> initFrags) 
    fragments.addAll(initFrags);
    notifyDataSetChanged();
  

  public void update(Fragment fragment, int position) 
    fragments.set(position, fragment);
    notifyDataSetChanged();
  

  @Override
  public Fragment getItem(int position) 
    return fragments.get(position);
  

  @Override
  public int getItemPosition(Object object) 
    if (!fragments.contains(object)) 
      return POSITION_NONE; // replace
    
    return super.getItemPosition(object);
  

  public void clear()
    fragments.clear();
    notifyDataSetChanged();
  

  @Override
  public int getCount() 
    return fragments.size();
  

  @Override
  public CharSequence getPageTitle(int position) 
    return "Title "+position; // TODO: 25/10/2017  
  

由于FragmentStatePagerAdapter 保存当前选定的片段及其旁边的片段,如果我在寻呼机中只有 2 个片段并且重新创建了 Activity,则更改片段列表并调用 notifyDataSetChanged(); 不会做任何事情。

在重新创建活动后,getItem(int position) 根本不会在 PagerAdapter 中触发。如果我在寻呼机中有 3 个以上的片段并且选择了第一个片段,那么移动到第 3 页将呈现该片段,并且移回第一个片段将最终呈现第一个片段。如果我在寻呼机中只有 2 个片段,那么在它们之间移动什么也不做,它们不会被渲染。

还有我在重新创建 Activity 后看到的内容。 FragmentManager 有这两个带有参考编号的片段,可以说是 (Fragment1@1000) 和 (Fragment2@1001),当我在寻呼机适配器中将新片段添加到 private List&lt;Fragment&gt; fragments、(Fragment1@1050) 和 (Fragment2@1051) 并调用时notifyDataSetChanged(),fragmentManager 不会更新它的 Fragment,它仍然会保留那些旧的 Fragment。

编辑:我想我发现了我的问题support FragmentPagerAdapter holds reference to old fragments 简而言之,即使在 cmets 中,也永远不要引用 PagerAdapter 之外的片段。

【问题讨论】:

你在哪里调用 init(List initFrags) 方法?? 当我从服务器获取数据时,我对其进行解析并从中创建片段,然后通过init 方法传递给 PagerAdapter。 【参考方案1】:

当您在 Fragment 之间移动时,请使用此代码更新 Fragment View,无论是两个还是多个。

@Override
public void setUserVisibleHint(boolean isVisibleToUser) 
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) 
        getFragmentManager().beginTransaction().detach(this).attach(this).commit();
        //getPlanListData();
    

【讨论】:

以上是关于FragmentStatePagerAdapter 视图分页器片段在活动重新创建后不显示的主要内容,如果未能解决你的问题,请参考以下文章

FragmentStatePagerAdapter 向 TextView 返回错误的位置

如何将 FragmentFactory 与 FragmentStatePagerAdapter 一起使用

getItem 函数在 FragmentStatePagerAdapter 中调用两次?

FragmentPagerAdapter和FragmentStatePagerAdapter区别?

FragmentStatePagerAdapter onPageSelected事件

Android - 使用 FragmentStatePagerAdapter 保存/恢复状态