在很多产品,尤其是电商类社区内的网页或者app中,我们经常会看到一个图片轮播墙,一页一页的广告/活动/商品介绍每隔一段时间就切换到下一张。那在安卓中我们该如何实现图片轮播器呢?面对自定义样式、自定义图片加载框架等等复杂的自定义需求,如何设计接口使得使用者可以很方便的自定义属性呢?接下来我从wangyeming/ImageBanner源码出发,探讨下我对这个小小功能框架的设计和实现。
图片轮播,一页两页,一页两页
首先明确需求:
- 图片轮播器由若干张不定的页面构成,每个页面上的元素包括:图片(必选) + 指示器(可选,可能是点点点,可能是数字等)
- 可以手势滑动图片的切换
- 闭环展示,第一张的左边是最后一张,最后一张的右边是第一张,无限循环播放。
看一下我画的设计结构图(很丑,轻拍)
可以看到有这么几个对象:
ImageBanner:自定义控件,包含定时任务管理器TimerController、增强ViewPager、指示器BannerIndicator。内部包含了诸如开启,关闭轮播等逻辑。设计为抽象类,通过钩子方法实现UI样式的自定义。
TimerController: 定时任务管理器, 无论是Timer也好,手动设计的定时Handler也好,它的职责就是执行定时任务,具体到图片轮播器里,职责就通知CirclePageAdapter和BannerIndicator切换到下一张。
CustomSwipeViewPager: 增强ViewPager, 方便随时禁止和开启手势滑动。
CirclePageAdapter: ViewPager的adapter, 通过在左右两边各增加一个伪Pager,滑动到0,和最后一个时,无动画切换到最后一个和0,从而实现循环滑动。同样设计为抽象类,ImageView的样式,图片加载的方式等同样通过钩子方法留出来供使用者自定义。
BannerIndicator: 指示器,设计成接口形式,实现该接口的自定义View都可以作为轮播器当中的指示器。最大程度自定义UI。
如何使用?
- 派生CirclePageAdapter,实现单个图片加载的样式和点击事件
1 | public class CustomCirclePageAdapter extends CirclePageAdapter<BannerImage> { |
- 自定义指示器(可选),实现BannerIndicator接口即可
1 | public class CustomBannerIndicator extends LinearLayout implements BannerIndicator { |
- 配置ImageBanner
1 | public class CustomImageBanner extends ImageBanner<BannerImage> { |
- 在xml中使用:
1 | <com.tianyeguang.imagebanner.banner.CustomImageBanner |
- 传入数据,正确的开启和关闭轮播的定时器:
1 |
|
具体的代码大家可以查看demo, demo的样式就是博文上的示意图,谢谢大家的阅读~