【问题标题】:Recyclerview inside nested fragment is not showing嵌套片段内的 Recyclerview 未显示
【发布时间】:2017-01-06 10:52:02
【问题描述】:

我有一个包含 viewpager 的片段。 viewpager 本身包含包含 recyclerview 和 textview 的片段。问题是 textview 显示在所有 5 个选项卡中,但 recyclerview 仅显示在 2-3 tabs(randomly) 。

这是我的代码

父片段

@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
toolbar = (Toolbar) fragmentActivity.findViewById(R.id.my_toolbar);
tabLayout = (TabLayout) fragmentActivity.findViewById(R.id.my_tablayout);
mCollapsingToolbarLayout = (CollapsingToolbarLayout)    fragmentActivity.findViewById(R.id.collapsing_toolbar_layout);
viewPager = (ViewPager) fragmentActivity.findViewById(R.id.my_pager);
    ((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
    ((AppCompatActivity)    getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
          adapter = new GameListPagerAdapter(getChildFragmentManager(),getContext());
    viewPager.setAdapter(adapter);
    viewPager.setCurrentItem(1);
    tabLayout.setupWithViewPager(viewPager);
}

ViewPager 适配器

public class GameListPagerAdapter extends FragmentStatePagerAdapter {

private final int PAGE_COUNT = 5;
private Context context;
private String pageTitle[] = {"Replaying", "Planning", "dropped", "playing","completed"};

public GameListPagerAdapter(FragmentManager fm, Context context) {
    super(fm);
    this.context = context;
}

@Override
public Fragment getItem(int position) {

    switch (position){

        case 0 :
            return GamesListPagerFragment.newInstance(GiantBomb.REPLAYING);
        case 1 :
            return GamesListPagerFragment.newInstance(GiantBomb.PLANNING);
        case 2 :
            return GamesListPagerFragment.newInstance(GiantBomb.DROPPED);
        case 3 :
            return GamesListPagerFragment.newInstance(GiantBomb.PLAYING);
        case 4:
            return GamesListPagerFragment.newInstance(GiantBomb.COMPLETED);

        default:
            return GamesListPagerFragment.newInstance(position);

    }

}

@Override
public int getCount() {
    return PAGE_COUNT;
}


@Override
public CharSequence getPageTitle(int position) {
    return pageTitle[position];
}


}

包含 textview 和 recyclereviw 的子 Fragment

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    Toaster.make(getContext(),"onActivity");
    recyclerView = (RecyclerView) getActivity().findViewById(R.id.recycler_view);
    recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
    realmResult =  realm.where(GameListDatabase.class).findAll();
    Toaster.make(getContext(),realmResult.size()+"");
    GameListAdapter adapter = new GameListAdapter(getContext(),realmResult,true);
    recyclerView.setAdapter(adapter);


}

【问题讨论】:

  • 为什么你在 switch 语句中使用 return 而不是 break

标签: android android-layout android-fragments android-recyclerview android-viewpager


【解决方案1】:

首先,不要在适配器的getItem(position) 方法中创建新项目。而是创建一个List 片段并将其填充到您的构造函数中,这样您就不会每次都创建新实例。

public class GameListPagerAdapter extends FragmentStatePagerAdapter {

    private Context context;
    private String pageTitle[] = {"Replaying", "Planning", "dropped", "playing", "completed"};
    private ArrayList<Fragment> fragments;

    public GameListPagerAdapter(FragmentManager fm, Context context) {
        super(fm);
        this.context = context;
        fragments = new ArrayList<>();
        fragments.add(GamesListPagerFragment.newInstance(GiantBomb.REPLAYING));
        fragments.add(GamesListPagerFragment.newInstance(GiantBomb.PLANNING));
        fragments.add(GamesListPagerFragment.newInstance(GiantBomb.DROPPED));
        fragments.add(GamesListPagerFragment.newInstance(GiantBomb.PLAYING));
        fragments.add(GamesListPagerFragment.newInstance(GiantBomb.COMPLETED));
    }

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

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

    @Override
    public CharSequence getPageTitle(int position) {
        return pageTitle[position];
    }
}

同时移动您的以下代码:

Toaster.make(getContext(),"onActivity");
    recyclerView = (RecyclerView) getActivity().findViewById(R.id.recycler_view);
    recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
    realmResult =  realm.where(GameListDatabase.class).findAll();
    Toaster.make(getContext(),realmResult.size()+"");
    GameListAdapter adapter = new GameListAdapter(getContext(),realmResult,true);
    recyclerView.setAdapter(adapter);  

从您的onActivityCreated 到您的子片段的onCreateView 方法。
如果您没有很多子片段,则可以将viewPager.setOffscreenPageLimit设置为您拥有的片段数,在本例中为 5。

【讨论】:

  • 非常感谢你,你是救生员:)。将上述代码从 onActivityCreated 移动到 onCreateView 时,它起作用了。这有什么原因吗?
  • 是的,onActivityCreated 在活动创建后被调用。如果您的片段是在活动的onCreate 中创建的,则可以使用其中的代码。但是在您的情况下,每次更改页面时都会创建片段的新实例(因为在您的 getItem 方法中您创建了新实例)。所以活动是在片段之前创建的,从而导致onActivityCreated 没有在您的某些片段中被调用。现在onCreateView 总是被调用,所以它会填充recyclerview。
【解决方案2】:

当碎片不在视野范围内时,它们往往会立即被销毁。您可以尝试以下方法:

1. 尝试使用FragmentPagerAdapter 而不是FragmentStatePagerAdapter,或者更好的是,直接扩展PagerAdapter

2.在您的子片段的onCreate() 中添加setRetainInstance(true)

3.尝试设置viewPager.setOffscreenPageLimit(5)

以上的一些组合应该可以工作。试试看。

【讨论】:

  • 感谢您的回答。不幸的是 2) 不适用于嵌套片段。我尝试了 3)和 1),但问题仍然存在。现在将通过扩展 PageAdapter 直接尝试。
猜你喜欢
  • 1970-01-01
  • 2017-03-20
  • 1970-01-01
  • 2015-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-18
  • 1970-01-01
相关资源
最近更新 更多