无限增加的ViewPager--InfiniteViewPage

作者: 剑小河 | 来源:发表于2018-10-17 16:38 被阅读12次

需求

无限增加的ViewPager在Android开发中没有无限循环的ViewPager常见,一般也就是日历这种情况。

效果图

初始数据只有一个0,向右翻页可以无限增长。


InfiniteViewPager操作效果.gif

思路

基本思路跟大多数先驱的做法差不多。

  1. 将PagerAdapter的getCount方法返回值为一个较大的数字,这里我返回了int类型的最大值,即Integer.MAX_VALUE;
  2. 初始item设置为Integer.MAX_VALUE的一半,即Integer.MAX_VALUE / 2;
  3. PagerAdapter的instantiateItem执行时根据position和数据列表计算出当前position应当显示的数据,先从数据列表里取对应数据,如果有,就返回给ViewHolder,如果没有,就从OnNeedAddDataCallback里获取;
  4. 每一个Item的数据和View都绑定在ViewHolder的实体内;
  5. 封装一个ViewHolderCreator,ViewHolder的回收、获取和更新都由ViewHolderCreator控制。

关于ViewHolderCreator

InfiniteViewPager工作流程 (1).png

上图所示
当setOffscreenPageLimit方法设置limit为2,即左右预加载数各为2,从ViewHolderCreator中获取5个空闲的ViewHolder,加载初始数据。当向右翻一页时,回收最左边的ViewHolder,放入空闲的ViewHolder队列中,获取一个空闲的ViewHolder放入右边,填充数据。

使用方法

在XML中配置或者直接new一个都可以

<com.riverlet.riverletviewpager.InfiniteViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="300dp" />
InfiniteViewPager viewpager = view.findViewById(R.id.viewpager);

或者

InfiniteViewPager viewpager = new InfiniteViewPager(getContext());

给LoopViewPager设置数据和ViewHolderCreator

 viewpager.setData(dataList, new InfiniteViewPager.ViewHolderCreator() {
            @Override
            public InfiniteViewPager.ViewHolder create() {
                TextView textView = new TextView(getContext());
                textView.setBackgroundColor(0xff199dff);
                textView.setTextColor(Color.WHITE);
                textView.setTextSize(50);
                textView.setGravity(Gravity.CENTER);
                textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
                return new InfiniteViewHolder(textView);
            }
        });

实现OnNeedAddDataCallback

viewpager.setOnNeedAddDataCallback(new InfiniteViewPager.OnNeedAddDataCallback<Integer>() {
          //  添加数据在数据列表最前
            @Override
            public Integer addFirst(int position, Integer integer) {
                return integer - 1;
            }

         //添加数据在数据列表最后
            @Override
            public Integer addLast(int position, Integer integer) {
                return integer + 1;
            }
        });

方法介绍

 /**
     * 设置基础数据和ViewHolderCreator
     *
     * @param dataList 数据列表
     * @param viewHolderCreator
     */
    public void setData(List dataList, @NonNull ViewHolderCreator viewHolderCreator) ;

/**
     * 获取当前显示Item的ViewHolder,即可获取当前显示的数据和View
     *
     * @return
     */
    public ViewHolder getCurrentItemViewHolder();


/**
     * 根据Item位置获取它的ViewHolder
     *
     * @param position
     * @return
     */
    public ViewHolder getViewHolderOfPosition(int position);


/**
     * 跳转到指定Data的位置
     *
     * @param data
     */
    public void setCurrentItemOfData(Object data);

 /**
     * 跳转到指定Data的位置
     *
     * @param data
     * @param smoothScroll 是否带滚动动画
     */
    public void setCurrentItemOfData(Object data, boolean smoothScroll);

 /**
     * 翻到下一页
     */
    public void nextPage();

  /**
     * 翻到上一页
     */
    public void lastPage();

/**
     * 设置当前页变化的监听
     * @param onCurrentPageChangeListener
     */
    public void setOnCurrentPageChangeListener(OnCurrentPageChangeListener onCurrentPageChangeListener);

 /**
     * 获取数据Map
     * @return
     */
    public Map<Integer, Object> getDataMap();

 /**
     * 设置新增数据的回调
     * @param onNeedAddDataCallback
     */
    public void setOnNeedAddDataCallback(OnNeedAddDataCallback onNeedAddDataCallback);

注意

  1. 无限增加不是真的无限增加,总页数为Integer.MAX_VALUE,即2147483647,比较大,初始设置在中间位置;
  2. 虽然总页数为2147483647,但实际加载的页数只有5个(当前显示页以及左右个两个);
  3. 因为实际加载页数只有5个,所以setCurrentItem跳转到其他未加载的页数时,会出现bug,
    所以在InfiniteViewPager里面setCurrentItem被阻断了,封装了setCurrentItemOfData作为跳转方法。

源码及Demo安装包

源码:ViewPagerDemo
Demo安装包:app-debug.apk
使用实力:自定义日历--RCalendarView

引申

无限循环的ViewPager:LoopViewPager

相关文章

  • 无限增加的ViewPager--InfiniteViewPage

    需求 无限增加的ViewPager在Android开发中没有无限循环的ViewPager常见,一般也就是日历这种情...

  • python nohup 文件无限增加

    用nohup命令会在当前的目录产生一个nohup.out的日志文件!时间长了特别的占磁盘空间! 处理办法一:1.关...

  • 基础概念及理念

    参考场景: 无限恐怖 场景无限无限循环,且难度增加。世界观:架空的世界观,创世三人组成的神组 和 被赋予能力的9个...

  • 宇宙是无限的

    我们决定了无限的面向:无限的富足亦或无限的匮乏。如果你想拥有的更多,对你所拥有的表示感谢,你就会发现它的数量增加了...

  • [线上经营]美乐家2020年2月第一讲@20200206

    一,ND张群红 名单:有意识去增加。方法无限多,每个月增加100个左右的新名单。 孩子的各种群,家长父母增加了20...

  • 使用react 实现一个无限滚动列表

    仓库地址:React 无限滚动demo 整体思路:通过定位将列表项展示在可视区域。滚动时,列表项dom不增加,增加...

  • 目送2

    每个人一生都有两本存折,一本无限的增加,而另一本将无限的减少,却是不对等的。

  • AlgorithmComplexity

    前言:函数的增长 算法的渐进效率:我们关心当输入规模无限增加时,算法的运行时间如何随着输入规模的变大而增加。例子:...

  • 增加专注力的呼吸法|《无限可能》摘抄

    此前,我们已经提到深呼吸可以作为晨间生活惯例。当然,当你需要重新调整自己的注意力时,这种方法同样适用,而且非常有效...

  • div模块高度随内容自动增加,浮动对齐的方法

    简要说明:我们要让子模块无限循环下去,子模块里面的高度又是没有设定的,高度随内容的增加而增加,那么问题来了怎么才能...

网友评论

    本文标题:无限增加的ViewPager--InfiniteViewPage

    本文链接:https://www.haomeiwen.com/subject/mgmlzftx.html