【问题标题】:Unlimited/Dynamic ViewPager in both directions双向无限/动态 ViewPager
【发布时间】:2013-05-11 03:13:53
【问题描述】:

ViewPager 的一个用例是我从未见过的完美实现。

ViewPager 或多或少是静态结构。将 Pages 添加到右侧(附加到 Model 并显示它)并不难,但是,应该有很好用的解决方案来扩展 PagerAdapter(或它的一些子类),以便它可以双向扩展。

我可以想象这样的适配器接口

boolean isEmpty()
boolean hasNext()
boolean hasPrevious()
Object  getNext()
Object  getPrevious()
Object  getItem(int position)

// or if using generics
T       getNext()
T       getPrevious()
T       getItem(int position)

类似于集合迭代器,但是是双向的。

其中索引/位置不限于从下到0,而是可以使用整数类型的整个范围。
也许不是基于数组的实现(从 0 到无限)。

我发现了这个“黑客”:dynamically add and remove view to viewpager
但正如我之前所说,我试图让它自然地工作,而不是维护 3,5,... 项目并强制 ViewPager 根据一些扭曲的逻辑改变当前位置

目前是否有足够的实施或是否有必要实施?
如果这将是一个全新的实现,我愿意赏金奖励答案。

【问题讨论】:

  • 我们可以在 ViewPager 中添加任意数量的视图。我已经在我的一个应用程序中实现了相同的功能。看看@FoamyGuy ViewPager 的简单演示,其中我们可以拥有无​​限数量的页面github.com/FoamyGuy/MathFactCards
  • @Pragnani 但你只是在正确的方向上扩展,我试图动态地进入两个方向,没有黑客攻击。
  • @Pragnani 你可以添加无限的页面,但只能在一个方向。我认为他的问题是不同的。
  • @MarekSebera 最近找到了...
  • 不知道谷歌日历是怎么实现的?感觉就像一个无限视图的寻呼机,因为您可以继续向左和向右滚动浏览这些日子。

标签: java android dynamic collections


【解决方案1】:

这会有帮助吗,

public static class MyAdapter extends FragmentPagerAdapter {
    public MyAdapter(FragmentManager fm) {
        super(fm);
    }

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

    @Override
    public Fragment getItem(int position) {
        return getFragmentBasedOnPosition(position);
    }

    private Fragment getFragmentBasedOnPosition(int position) {
        int fragmentPos = position % 3; // Assuming you have 3 fragments
        switch(fragmentPos) {
            case 1:
            return Fragment1.newInstance();
            case 2:
            return Fragment2.newInstance();
            case 3:
            return Fragment3.newInstance();
        }
    }
}

然后,

mPager.setCurrentItem((int)(Integer.MAX_VALUE/2)); // 假设 mPager 是你的 ViewPager

【讨论】:

  • 这会有所帮助,谢谢,但在我看来,这仍然是一种奇怪的解决方案。
  • 它不适用于 FragmentStatePagerAdapter,因为它需要计算每个片段。并导致内存溢出
【解决方案2】:

使用负位置值代表非常远离 ViewPager 使用的自然顺序,根本不是适配器问题。请在 Android SDK 的支持包源中查看 ViewPager 的源代码。例如,这是一个 setCurrentItemInternal 私有实现:

void setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int velocity) {
    if (mAdapter == null || mAdapter.getCount() <= 0) {
        setScrollingCacheEnabled(false);
        return;
    }
    if (!always && mCurItem == item && mItems.size() != 0) {
        setScrollingCacheEnabled(false);
        return;
    }

    if (item < 0) {
        item = 0;
    } else if (item >= mAdapter.getCount()) {
        item = mAdapter.getCount() - 1;
    }
    final int pageLimit = mOffscreenPageLimit;
    if (item > (mCurItem + pageLimit) || item < (mCurItem - pageLimit)) {
        // We are doing a jump by more than one page.  To avoid
        // glitches, we want to keep all current pages in the view
        // until the scroll ends.
        for (int i=0; i<mItems.size(); i++) {
            mItems.get(i).scrolling = true;
        }
    }
    final boolean dispatchSelected = mCurItem != item;
    populate(item);
    scrollToItem(item, smoothScroll, velocity, dispatchSelected);
}

如您所见,ViewPager 明确假定没有负位置值。

【讨论】:

  • 什么是结论?我不想使用负索引。我需要根据我的自定义模型在两个方向上无限制地遍历集合。我直接说,这个解决方案可能不应该基于Array,因为我们必须处理负索引。
  • 您写道:“索引/位置不限于从 0 下方开始,但可以使用整个整数类型范围。”您想在哪里使用这些索引?如果在获取/设置当前页面或 onChange 处理程序中,则会出现上述问题。如果 ViewPager 看不到负索引,那么拥有这样的索引是什么意思?请详细说明...
  • 我在谈论可能元素的范围,在界面大纲中我不需要索引,但我需要在两个方向上动态扩展集合。因此调用 getPreviousItem 不会以 Element(0) 结束,而是取决于其他一些条件,在自定义模型中实现。
  • 所以,如果我理解正确,问题可以简化为使用 getModelPostion(item) 方法扩展普通 List 并使用代码扩展 List.add ,更新 positon-modelPosition 映射。我说的对吗?
  • 你可以让它在两个方向上循环,并产生像无限页一样的效果。同时在下一个或上一个循环槽上更改视图寻呼机的内容,例如前 5 页内容将是某些内容,对于接下来 5 个内容获取更改,对于后 5 个内容从历史记录中获取更改,您必须为每个页面维护一个历史记录广告位(5 页)。
猜你喜欢
  • 1970-01-01
  • 2015-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多