前言:
在android开发中经常会用到Banner,一直想自己实现一个,但是都没有去做过。
实现banner轮播的一个比较困难的地方就是实现无限轮播。网上有很多实现无线轮播的办法,有些比较好,但是稍微要麻烦了一些。下面这种方式是我改进的一种。本人觉得效果还不错。请看PagerAdapter代码
轮播核心部分
//重写PagerAdapter来实现轮播效果
inner class MPagerAdapter(val views:List<View>) :PagerAdapter(){
//初始化item
override fun instantiateItem(container: ViewGroup?, position: Int): Any {
val view = views[position % views.size]
container?.removeView(view)
container?.addView(view)
return view
}
//销毁item,开始在这里销毁view的时候,但是总是报错没有销毁,所以销毁工作也改到instantiateItem里面了
override fun destroyItem(container: ViewGroup?, position: Int, `object`: Any?) {
}
override fun isViewFromObject(view: View?, `object`: Any?): Boolean {
//这个一般直接按如下返回就行
return view == `object`
}
//为了无限循环播放
/**
* 实现无线循环的方式可以直接在getCount里面返回Int.MAX_VALUE,
* 但是在这种情况下有个问题:最开始的时候不可以向左滑动,这个问题有很多解决方案,我的解决方案是在设置Views的时候将
* viewPager的currentItem调到Int.MAX_VALUE的中间数值
*/
override fun getCount(): Int {
return Int.MAX_VALUE
}
在上面的代码的注释中我有说在初始化时把viewPager的currentItem设置为Int.MAX_VALUE的中间值,下面是具体的设置。
//设置轮播内容
fun setViews(views:List<View>){
this.views = views
viewPager?.adapter = MPagerAdapter(views)
//把viewPager的currentItem调到Int.MAX_VALUE的中间值
viewPager?.currentItem = views.size * ((Int.MAX_VALUE/views.size)/2)
//初始化indicator
initIndicator()
}
经过上面的两个简单设置,我们的banner已经可以无线轮播了,而且在最初情况下,banner也可以向右滑动。
Banner的代码
代码里面有详细的注释,我就不过多的解释了。
/**
* 后期可能添加内容
* 1、设置轮播动画
* 2、设置指示器样式等
* 3、异步加载banner的view
*/
class Banner :RelativeLayout , OnPageChangeListener{
private val defaultTimeInterval = 1800
private var views:List<View>? = null
private var indicatorViews = ArrayList<View>()
private var timeInterval = defaultTimeInterval
private var viewPager:ViewPager? = null
private var indicator:LinearLayout? = null //指示器
private var itemClickListener:OnBannerClickedListener? = null
private var currentIndex = 0 //当前播放位置
constructor(context: Context) : super(context) {
}
constructor(context: Context, attributeSet: AttributeSet?) : super(context, attributeSet) {
setAttrs(attributeSet)
}
constructor(context: Context, attributeSet: AttributeSet?, defStyleAttributeSet: Int) : super(context, attributeSet, defStyleAttributeSet) {
setAttrs