9

我想要的是:

我一直在尝试在 Android中实现两个定向 Endless viewpager ,从左到右从右到左

我做了什么:

我已经实现了Endless viewpager adapter,它适用于从右到左的方向,我已经将当前项目位置设置为viewPager.setCurrentItem(Integer.MAX_VALUE/2);.

参考:

在此处输入图像描述

帮助将不胜感激。

4

4 回答 4

10

尝试检查以下FragmentPagerAdapter内容以获得无尽的 viewpager 适配器:

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 0:
        return Fragment1.newInstance();
        case 1:
        return Fragment2.newInstance();
        case 2:
        return Fragment3.newInstance();
    }
 }
}

我在这里找到了解决方案。

我希望它对你有帮助。

于 2016-04-03T11:56:28.200 回答
3

我已经制定了自己的解决方案。我创建了一个ViewPager,它支持无限循环效果,智能自动滚动,兼容任何指标,使用方便。它特别将其用作带有简单项目页面的应用程序横幅。

我的自定义 ViewPager 可以:

  • 即插即用,简单易用
  • 无限循环项目
  • 自动滚动项目,允许配置,活动/片段恢复/暂停时自动恢复/暂停
  • 如果只有 1 个项目,则不会滚动或循环
  • 兼容多种指标

Github 链接:https ://github.com/kenilt/LoopingViewPager

在此处输入图像描述

希望能帮助到你!

于 2020-03-15T14:05:48.530 回答
2

实现这一目标的一种简单方法ViewPager2是使用 3 个基本思想:

  1. 将数据模型集合的第一项和最后一项分别添加到同一集合的末尾和开头。例如listOf(1, 2, 3, 4, 5)应该变成listOf(5, 1, 2, 3, 4, 5, 1).
  2. 设置寻呼机时,将其设置为从索引 1 开始。
  3. 当用户滚动到索引 0 时,让寻呼机立即滚动到倒数第二个索引。当用户滚动到最后一个索引时,让寻呼机立即滚动到索引 1。

执行此操作的一些示例代码如下:

1.

private fun <T> List<T>.prepareForTwoWayPaging(): List<T> {
    val first = first()
    val last = last()
    return toMutableList().apply {
        add(0, last)
        add(first)
    }
}
pager.setCurrentItem(1, false)
pager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
    override fun onPageScrolled(
        position: Int,
        positionOffset: Float,
        positionOffsetPixels: Int
    ) {
        // We're only interested when the pager offset is exactly centered. This
        // will help create a convincing illusion of two-way paging.
        if (positionOffsetPixels != 0) {
            return
        }
        when (position) {
            0 -> pager.setCurrentItem(adapter.itemCount - 2, false)
            adapter.itemCount - 1 -> pager.setCurrentItem(1, false)
        }
    }
})

警告:此代码不协调任何TabLayout或空的数据模型集合。

于 2021-03-15T00:55:08.520 回答
1

建议的解决方案是正确的,但要获得结果,您需要将 viewpager 的初始值设置为 Integer.MAX_VALUE/2。

无论如何,我不太喜欢这种解决方案,将 getCount 设置为返回 Integer.MAX_VALUE 会对应用程序性能产生巨大影响。

为了避免这个问题,我想出了一个解决方案:

onPageScrollStateChanged 监听器

我只是重新排序片段列表,更新 viewPager 并移动到没有动画的新页面,结果是双向循环:

mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener()
{
  Boolean first = false;
  Boolean last = false;

  @Override
  public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
  {}

  @Override
  public void onPageSelected(int position)
  {
    if (position == 0)
    {
      first = true;
      last = false;
    }
    else if (position == mainFragmentList.size() -1)
    {
      first = false;
      last = true;
    }
    else
    {
      first = false;
      last = false;
    }
  }

  @Override
  public void onPageScrollStateChanged(int state)
  {
    if (first && state == ViewPager.SCROLL_STATE_IDLE)
    {
      // Jump without animation
      Fragment fragment = mainFragmentList.get(mainFragmentList.size() -1);
      mainFragmentList.remove(mainFragmentList.size() -1 );
      mainFragmentList.add(0,fragment);
      mainPagerAdapter.setData(mainFragmentList);
      mainPagerAdapter.notifyDataSetChanged();
      Log.e(TAG,mainFragmentList.toString());
      mainViewPager.setCurrentItem(1,false);
    }
    if(last && state == ViewPager.SCROLL_STATE_IDLE)
    {
      // Jump without animation
      Fragment fragment = mainFragmentList.get(0);
      mainFragmentList.remove(0);
      mainFragmentList.add(fragment);
      mainPagerAdapter.setData(mainFragmentList);
      mainPagerAdapter.notifyDataSetChanged();
      Log.e(TAG,mainFragmentList.toString());
      mainViewPager.setCurrentItem(mainFragmentList.size()-2,false);
    }
  }
});

这就是这里发生的情况:在这个例子中,我们有 4 个片段 ABCD 如果用户在片段 A(第一个)上,新的 List 将变为: DABC [删除最后一个并作为第一个推送] 我更新 ViewPager 并移动(没有动画)再次到片段 A 所以索引 1。现在用户可以继续向左滚动,将找到片段 D。

与最后一个片段相同:如果用户在片段 D(最后一个)上,则从 ABCD 重新开始,新列表将变为:BCDA [删除第一个并作为最后一个推送]我更新 ViewPager 并再次移动(没有动画)到片段 D 所以索引 mainFragmentList.size()-2。现在用户可以继续向右滚动,将找到片段 A。

记住要实现 FragmentStatePagerAdapter 而不是 FragmentPagerAdapter

于 2019-09-03T17:59:22.973 回答