从无限的ViewPager中的最终权利开始

时间:2015-04-10 13:10:38

标签: android android-viewpager

我有一个ViewPager,我想给理论上无限量的页面。每个页面都包含一个链接到日期的文本,并且滑动用户应该能够看到之前日期的文本。他无法查看未来日期的文本。

为此,我将ViewPager作为计数Integer.MAX_VALUE。但是,我希望默认页面是最终正确的页面,因此向左滑动可以显示以前日期的文本。默认情况下,第一个位置最终会被保留。

这是我的代码:

private class PagerAdapter extends FragmentStatePagerAdapter {
    public PagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int i) {
        return new DailyTextFragment();
    }

    @Override
    public int getCount() {
        return Integer.MAX_VALUE;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return "OBJECT " + (position + 1);
    }
}

我尝试过setCurrentPosition(Integer.MAX_VALUE),但是Android会尝试计算之前的所有页面最后一个页面,这很多,我得到java.lang.OutOfMemoryError

我已经考虑过欺骗ViewPager认为触摸事件的x坐标是镜像的,但不知道如何做如果这是最好的解决方案。设置这种界面的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

经过一些调试后,我发现了以下内容:

  • 当您尝试设置setCurrentPosition(Integer.MAX_VALUE)时,FragmentStatePageAdapter将尝试生成ArrayList个2147483647个NULL对象。因此,你的内存不足。
  • 实际上,只有前两个片段(0和1)被实例化:ArrayList的其余部分是NULL值。

这在instantiateItem()中实现如下:

while (mFragments.size() <= position) {
    mFragments.add(null);
}

现在,我们可以做的是通过覆盖此方法来欺骗FragmentStatePageAdapter,如下所示:

@Override
public Object instantiateItem(ViewGroup container, int position) {
    if (position < 2) {
        return super.instantiateItem(container, position);
    } else {
        return super.instantiateItem(container, Integer.MAX_VALUE - position - 1);
    }
}

因此,对于前两个对象,我们给super方法赋予实数 - 对于其他对象,我们给它Integer.MAX_VALUE - position。现在,您可以在活动的onCreate方法中安全地执行此操作,例如:

pager.setCurrentItem(Integer.MAX_VALUE, false);

像这样,ViewPager将从最终权利开始,使用对象0.因此,你的对象是相反的:对象0是最后一个,在最右边,并且在你的片段左边更远增长指数。

您还需要覆盖destroyItem(),因为它具有相同的循环来添加NULL值。像这样:

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    if (position < 2) {
        super.destroyItem(container, position, object);
    } else {
        super.destroyItem(container, Integer.MAX_VALUE - position - 1, object);
    }
}

这可能不是这样做的首选方式,但它对我有用。