防止ViewPager破坏屏幕外视图

时间:2011-12-01 21:43:35

标签: android android-fragments android-viewpager

我有一个ViewPager连接到一个显示三个片段的FragmentPagerAdapter。当ViewPager从当前位置多次滑动时,它似乎会破坏托管片段的视图。

这些视图都是简单的列表,这种优化是完全没必要的,所以我想禁用它。它导致一些视觉问题,因为列表具有应用于它们的布局动画,并且这些动画在被销毁和重新创建后正在重放。它还会每次显示滚动条介绍动画(滚动条可以短暂显示以指示可以滚动),这可能会分散注意力,并且用户当前的滚动位置会在此过程中丢失。

它也不会加载第三个片段,直到第一次滑动发生,这是有问题的,因为每个片段处理自己的服务调用,我更喜欢在活动加载时同时关闭所有三个片段。延迟第三次服务呼叫不太理想。

有没有办法说服ViewPager停止这种行为并将我的所有片段保存在内存中?

4 个答案:

答案 0 :(得分:319)

在支持包的revision 4中,ViewPager中添加了一种方法,允许您指定要使用的屏幕外页面数,而不是默认值1。

在您的情况下,您要指定2,这样当您在第三页时,第一页不会被销毁,反之亦然。

mViewPager = (ViewPager)findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(2);

答案 1 :(得分:6)

默认情况下,ViewPager会在您滑动页面时重新创建片段。为了防止这种情况,您可以尝试以下两种方法之一:

1。在片段的onCreate()中,调用setRetainInstance(true)。

2. 如果片段数量固定且&相对较小,然后在你的onCreate()中添加以下代码:

ViewPager mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(3);

如果我没记错的话,第二种选择更有希望。但我敦促你们两个都试试,看看哪个有效。

答案 2 :(得分:3)

“在空闲状态下设置应保留在视图层次结构中当前页面任一侧的页面数。超出此限制的页面将在需要时从适配器重新创建。”

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

答案 3 :(得分:0)

选择的答案很好,但对我而言却不是很好。这是因为我有很多片段(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();
    }
}