我有一个 ViewPager 连接到显示三个片段的 FragmentPagerAdapter。当 ViewPager 从当前位置滑动不止一次时,它似乎会破坏托管片段的视图。
这些视图都是简单的列表,完全不需要这种优化,所以我想禁用它。这会导致一些视觉问题,因为列表应用了布局动画,并且这些动画在它们被销毁和重新创建后会被重放。它还每次都显示滚动条介绍动画(滚动条短暂可见以指示可以滚动),这可能会分散注意力,并且用户当前的滚动位置会在此过程中丢失。
在第一次滑动之前它也不会加载第三个片段,这是有问题的,因为每个片段都处理自己的服务调用,我希望在活动加载时同时触发所有三个片段。延迟第三次服务呼叫并不理想。
有什么方法可以说服 ViewPager 停止这种行为并将我所有的片段保存在内存中?
在支持包的 revision 4 中,向 ViewPager 添加了一个方法,该方法允许您指定要使用的屏幕外页面数,而不是默认值 1。
在您的情况下,您要指定 2,这样当您在第三页上时,第一页不会被破坏,反之亦然。
mViewPager = (ViewPager)findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(2);
默认情况下,ViewPager 会在您滑动页面时重新创建片段。为了防止这种情况,您可以尝试以下两种方法之一:
1. 在片段的 onCreate() 中,调用 setRetainInstance(true)。
2. 如果片段数量固定且相对较少,则在您的 onCreate() 中添加以下代码:
ViewPager mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(3);
如果我没记错的话,第二种选择更有希望。但我敦促您尝试两种方法,看看它们中的哪一种有效。
“设置在空闲状态下视图层次结构中当前页面的任一侧应保留的页面数。超出此限制的页面将在需要时从适配器重新创建。”
选择的答案很好,但对我来说并不是很好。这是因为我有很多片段 (20-30),因此如果我使用 setOffscreenPageLimit(30),使用 ViewPager 的活动将需要很长时间才能加载。在我的情况下,我必须实现 destroyItem() 方法(在 ViewPager 的 Adapter 类中)并删除对超级函数的调用。这是伪代码
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
}
现在,如果您想要更多上下文,这里是整个 ViewPagerAdapter 类
public class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> listFragment =
new ArrayList<>();
public ViewPagerAdapter(@NonNull FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
@NonNull
@Override
public Fragment getItem(int position) {
return listFragment.get(position);
}
@Override
public int getCount() {
return listFragment.size();
}
/*This is the method I was taking about*/
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
}
public void addFragment(Fragment fragment)
{
listFragment.add(fragment);
notifyDataSetChanged();
}
}
不定期副业成功案例分享