1.gitbub地址
implementation 'io.github.youth5201314:banner:2.2.3'
2.核心功能
- Banner(com.youth.banner.Banner)
• 轮播控件容器
• 内部持有一个 RecyclerView + ViewPager2 实现循环滑动
• 负责轮播控制(自动播放、手势滑动、翻页) - BannerAdapter
• 用于给 Banner 提供数据和创建 View
• 类似 RecyclerView.Adapter - Indicator
• 指示器(圆点、数字、方块)
• 可自定义或使用内置的 CircleIndicator - BannerViewHolder
• 单个轮播页的 View 容器
• 支持任意自定义布局
3.自定义 Item View
步骤 1:创建数据类
data class BannerData(
val imageUrl: String,
val title: String
)
步骤 2:创建自定义 Adapter
继承 BannerAdapter<T, VH>:
class MyBannerAdapter(data: List<BannerData>) :
BannerAdapter<BannerData, MyBannerAdapter.BannerViewHolder>(data) {
// 创建自定义 ViewHolder
class BannerViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val imageView: ImageView = view.findViewById(R.id.image)
val titleView: TextView = view.findViewById(R.id.title)
}
override fun onCreateHolder(parent: ViewGroup, viewType: Int): BannerViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_banner, parent, false)
return BannerViewHolder(view)
}
override fun onBindView(holder: BannerViewHolder, data: BannerData, position: Int, size: Int) {
// 绑定数据
Glide.with(holder.itemView)
.load(data.imageUrl)
.into(holder.imageView)
holder.titleView.text = data.title
}
}
🔹 item_banner.xml 可以完全自定义(例如图片 + 文本 + 按钮)
⸻
步骤 3:在 Activity/Fragment 中使用
val list = listOf(
BannerData("https://xxx/image1.jpg", "标题1"),
BannerData("https://xxx/image2.jpg", "标题2")
)
binding.banner.apply {
adapter = MyBannerAdapter(list) // 设置自定义Adapter
indicator = CircleIndicator(context) // 设置指示器
isAutoLoop(true) // 自动轮播
setLoopTime(3000) // 3秒切换
start()
}
4.自定义 Indicator(指示器)
com.youth.banner 提供了 Indicator 接口,可以自定义任何形式的指示器。
示例:数字指示器
class NumberIndicator(context: Context) : FrameLayout(context), Indicator {
private val textView = TextView(context).apply {
setTextColor(Color.WHITE)
textSize = 16f
}
init {
addView(textView, LayoutParams(WRAP_CONTENT, WRAP_CONTENT, Gravity.BOTTOM or Gravity.END))
}
override fun onPageChanged(count: Int, current: Int) {
textView.text = "${current + 1}/$count"
}
}
使用
binding.banner.indicator = NumberIndicator(this)
5.自定义轮播 View(扩展 Banner)
如果你要对整个 Banner 行为进行自定义,例如:
• 改变滑动速度
• 自定义过渡动画
• 改变布局结构(例如添加渐变蒙层)
可以继承 Banner<T, Adapter>:
class MyCustomBanner @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : Banner<BannerData, MyBannerAdapter>(context, attrs) {
init {
// 可以自定义ViewPager2的各种属性
(viewPager2.getChildAt(0) as RecyclerView).apply {
// 自定义切换动画或者间距
setPadding(40, 0, 40, 0)
clipToPadding = false
}
}
}
6.常见扩展点
6.1. 自定义过渡动画
banner.setPageTransformer(ZoomOutPageTransformer())
6.2. 监听点击事件
banner.adapter.setOnBannerListener { data, position ->
Toast.makeText(context, "点击了第$position个", Toast.LENGTH_SHORT).show()
}
6.3. 自定义轮播时长
banner.setLoopTime(5000) // 5秒
6.4. 手动开始/停止轮播
banner.start()
banner.stop()
7.源码内部原理简析
• 核心是 ViewPager2 + RecyclerView
• 数据由 BannerAdapter 驱动
• 无限循环是通过 虚拟 position 映射 实现(如 1000 * size)
• 生命周期感知
• Banner 内部实现了 LifecycleObserver:
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun start()
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun stop()
• 所以放在 Fragment/Activity 内无需手动管理轮播暂停。
8.实例
mBinding.bannerBackpack.setAdapter(
BackpackBannerAdapter().apply { this.setDatas(it) })
.addBannerLifecycleObserver(this) //添加生命周期观察者
.setIndicator(RectangleIndicator(mContext))
.setIndicatorGravity(IndicatorConfig.Direction.RIGHT)
.setIndicatorSelectedColor("#FFFFFFFF".toColorInt())
.setIndicatorNormalColor("#80FFFFFF".toColorInt())
.setIndicatorRadius(UiUtil.dp2Px(3, mContext))
.setIndicatorHeight(UiUtil.dp2Px(6, mContext))
.setIndicatorWidth(UiUtil.dp2Px(6, mContext), UiUtil.dp2Px(15, mContext))
.setOnBannerListener { data, position ->
if (data is BannerResult) {
if (data.target == 0) {
return@setOnBannerListener
}
if (data.jump?.startsWith("http") == true) {
WebViewActivity.actionStart(this@BackpackActivityNew, data.title ?: "", data.jump ?: "", hideHead = false, finish = false)
} else {
SchemeFilterActivity.openSchemeFilterActivity(mContext, data.jump ?: return@setOnBannerListener)
}
}
}
⸻
总结
在 com.youth.banner 中,自定义 View 的方式主要有:
1. 自定义 Item Layout(通过 Adapter + ViewHolder)
2. 自定义 Indicator(实现 Indicator 接口)
3. 自定义 Banner 容器行为(继承 Banner 类,修改 ViewPager2 行为)
大多数需求只需要 自定义 Adapter + 自定义 item_layout 就可以实现复杂效果,比如卡片式、带按钮的轮播页。