Android-自定义轮播Banner-Viewpaper2实现+贪吃蛇原点指示器+触摸暂停轮播处理

541 阅读3分钟

接着上一篇MonkeyLei:更全的ViewPager2的使用方式总结, Glide加载https空白问题(http也要修改配置) 我们继续完善这个Banner。让其更像一个轮播组件。目前模块已经添加到https://github.com/FanChael/MVVM 下面, lib_banner模块。

先看效果,基本已经完善, 针对内存也做了一些处理, 可能还有很多细节和bug没完善!

具体的代码可以进上面工程去看模块,没多少文件和代码, 我简单截图标注做个注释如下:

接下来,你还可以考虑封装成开源组件,当然在你觉得性能和内存,以及显示问题都完善的情况下,你可以对比其他优秀的开源组件,然后看看你的是否更具有优势和特色。。。 另外我描述下实现过程中的几个要点:

  1. 继承ViewGroup,为了增加Banner圆角,自行测量和布局,主要是为了将addView进来 的Viewpaper2设置一个margin,让其内容在边框里面,不超区边框,然后实现上层绘制覆盖一个圆角的效果重写dispatchDraw,这里做最后的绘制.

  1. 搞定了边框绘制,指示器绘制相对容易一些:解决下绘制的位置,然后判断当前是第几个页面,此时指示器颜色有所区别,然后当滚动一定距离,绘制贪吃蛇效果,当滚动到下一个位置,刷新指示器颜色效果 - 重点是ViewPager2.OnPageChangeCallback回调的监听以及相关位置的计算判断 建议打印如下日志去分析,如何实现圆点贪吃蛇和切换:
@Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        this.current_pos = position;
        this.positionOffset = positionOffset;
        viewGroup.invalidate();
    }

由于无线轮播,所以计算当前位置需要current_pos % count,另外上面回调里面的positionOffset整好是一个百分比小数,整好做贪吃蛇宽度的百分比,实现贪吃蛇效果。。

for (int i = 0; i < count; ++i) {
            int last_pos = current_pos % count;
            // 画贪吃蛇
            if (last_pos < (count - 1)) {
                if (positionOffset >= 0.0000001) {
                    canvas.drawLine(
                            leftX + last_pos * (dot_space + dot_radius * 2),
                            topY, leftX + last_pos * (dot_space + dot_radius * 2) + (dot_space + dot_radius * 2) * positionOffset,
                            topY, snakePaint);
                }
            }
            // 画原点
            if (i == last_pos) {
                dotPaint.setColor(dot_selected_color);
            } else {
                dotPaint.setColor(dot_color);
            }
            canvas.drawCircle(
                    leftX + (dot_space + dot_radius * 2) * i,
                    topY,
                    dot_radius, dotPaint);
        }
  1. 当Touch down的时候,停止轮播,Viewpaper2已经提供回调onPageScrollStateChanged处理 - 注意外部setTouchEvent事件是无效的。。另外ViewPaper2不能继承,所以不能像Viewpaper那样重写DispatchEvent事件来处理哟。
@Override
    public void onPageScrollStateChanged(int state) {
        // 返回Down和UP事件回调
        if (null != mOnTouchListener) {
            if (ViewPager2.SCROLL_STATE_DRAGGING == state) {
                mOnTouchListener.onTouch(MotionEvent.ACTION_DOWN);
            } else if (ViewPager2.SCROLL_STATE_IDLE == state) {
                mOnTouchListener.onTouch(MotionEvent.ACTION_UP);
            }
        }
    } 

综上一系列构想和实现,以及完善过程遇到的问题,目前基本都解决了。。效果也还好,不差,至少满足了项目需求。。 你可以扩展为自己的组件库。。或者搞得更好,开源一把。。最近忙准备面试,所以就不搞了。。。各位大佬,共勉。。。。到目前我的MVVM工程已经自定义了两个组件,一个刷新,一个轮播,刷新目前还有些问题。。。后续完善。。。除了备战,将会继续完善简化这个工程模板。 供参考学习...