Android Banner - ViewPager2 01
Android Banner - ViewPager2 01
今天我们使用ViewPager2 实现一个banner
ViewPager2 对比 ViewPaer,支持横向和竖向的滚动。(大家也可以尝试使用RecyclerView实现Banner)
主要实现的功能和viewpager实现相同
- 无限轮播
- 代码抽取
- 动效
- 动态更新(插入或删除单个数据)
首先,viewpager2这个类被final修饰,意味着,我们不能使用继承的方式来扩展这个类,只能使用聚合的方式来处理(继承其他类,来添加viewpager2)
VP2Banner
我们使用FrameLayout作为父布局,包裹ViewPager2,方便后续扩展(比如加导航点)
class VP2Banner : FrameLayout {
private lateinit var viewPager2: ViewPager2
constructor(context: Context) : this(context, null)
constructor(context: Context, attributeSet: AttributeSet?) : this(context,
attributeSet, 0)
constructor(context: Context, attributeSet: AttributeSet?, style: Int) : this(
context, attributeSet, style, 0)
constructor(context: Context, attributeSet: AttributeSet?, style: Int, styleRes: Int) : super(
context, attributeSet, style, styleRes) {
// 初始化view,添加viewpager2到容器内部
viewPager2 = ViewPager2(context)
// 处理自定义属性
// 添加viewpager2
addView(viewPager2)
}
}
VP2Adapter
ViewPager2基于RecyclerView实现的,所以它的adapter也是和RecyclerView的使用一样。
abstract class VP2Adapter<T, H : RecyclerView.ViewHolder>(private val loop: Boolean) :
RecyclerView.Adapter<H>() {
private val mData = mutableListOf<T>()
private var mListener: ClickListener<T>? = null
fun setData(data: List<T>) {
mData.clear()
if (loop && mData.size > 1) {
mData.add(data[data.size - 1])
mData.addAll(data)
mData.add(data[0])
} else {
mData.addAll(data)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): H {
val holder = createHolder(parent, viewType)
holder.itemView.setOnClickListener { view ->
mListener?.let {
val position = holder.adapterPosition
it.onClick(position, mData[position])
}
}
return holder
}
override fun getItemViewType(position: Int) = getItemType(position)
override fun getItemCount(): Int = mData.size
override fun onBindViewHolder(holder: H, position: Int) {
bindData(holder, mData[position])
}
abstract fun bindData(holder: H, data: T)
abstract fun getItemType(position: Int): Int
abstract fun createHolder(parent: ViewGroup, viewType: Int): H
interface ClickListener<T> {
fun onClick(position: Int, data: T)
}
}
无限循环
和使用ViewPager实现方式一致,不再描述
单页显示多个
fun setPageMargin(width: Int) {
val realWidth = dp2px(width + 0F).toInt()
viewPager2?.setPageTransformer(MarginPageTransformer(realWidth))
viewPager2?.let { vp ->
val recyclerView = vp.getChildAt(0) as? RecyclerView
recyclerView?.let { rv ->
rv.setPadding(realWidth+40, 0, realWidth+40, 0)
rv.clipToPadding= false
}
}
}
参考地址:https://github.com/huyuqiwolf/BannerGitHub - huyuqiwolf/Banner