具体思路是利用clipToPadding属性和clipChildren属性
给ViewPager2设置一个内边距padding,添加clipToPadding属性,然后设置clipChildren,让父布局不要限制子View,设置padding后,padding部分的滑动事件不会被内部的RecyclerView收到,所以这里setOnTounchListener,直接交给rv。
viewPager2 = ViewPager2(context).also {
it.setPadding(pLeft.toInt(), pTop.toInt(), pRight.toInt(), pBottom.toInt())
it.clipToPadding = false
it.clipChildren = false
it.setPageTransformer(transferMode)
it.offscreenPageLimit = 2
val rv = it.getChildAt(0).also { v ->
v.overScrollMode = View.OVER_SCROLL_NEVER
}
it.setOnTouchListener { _, event ->
it.performClick()
return@setOnTouchListener rv.onTouchEvent(event)
}
addView(
it, LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT,
)
)
}
然后就是无限轮播的思路了,给需要展示的图片List,在列表头增加最后一张图片,列表尾增加第一张图片,这里是重写数据提交的相关函数实现。
abstract class BannerAdapter>(diff: DiffUtil.ItemCallback) :
ListAdapter(diff) {
val bannerCount
get() = if (itemCount <= 1) itemCount else itemCount - 2
private fun addFirstAndLast(list: MutableList?) {
list?.apply {
if (size <= 1) return
add(first())
add(0, list[lastIndex - 1])
}
}
override fun submitList(list: MutableList?) {
addFirstAndLast(list)
super.submitList(list)
}
override fun submitList(list: MutableList?, commitCallback: Runnable?) {
addFirstAndLast(list)
super.submitList(list, commitCallback)
}
}
给ViewPager2注册监听,根据当前下标进行页面设置,当下标为0的时候跳转到最后一张图片,即
lastIndex - 1,当下标为lastIndex时,跳转到第一张图,即下标1
viewPager2.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback())
private fun judgePage(position: Int, state: Int) {
if (state == ViewPager2.SCROLL_STATE_IDLE) {
vp2Adapter?.let {
when (
position
) {
0 -> {
viewPager2.setCurrentItem(it.itemCount - 2, false)
}
vp2Adapter?.itemCount?.minus(1) -> {
viewPager2.setCurrentItem(1, false)
}
}
}
}
}
切换动画可以通过ViewPager2设置setPageTransformer实现,回调的page是某一页,其中position,个人理解是,当前页下标始终为0,其余的,左边依次减一,右边依次加一,滑动过程中会出现小数,例如,下标为-1的页,在滑动到下标为0的过程中,position取值为[-1, 0]。
例子:
初始position
0 1 2 3 4
向右滑动一位,即第二张图成为当前的图,下标为
-1 0 1 2 3
在上一步的基础下,向左滑动,下标为
0 1 2 3 4
在第二步的基础上再向右边滑动一页,下标为
-2 -1 0 1 2
中间大两边小
private class BigSmall : ViewPager2.PageTransformer {
override fun transformPage(page: View, position: Float) {
//这个判断是对所有不是当前页的进行处理,当前页:viewpager2.getCurrentItem获取的下标
if (position < -1 || position > 1) {
page.alpha = 0.5f
page.scaleX = 0.8f
page.scaleY = 0.8f
return
}
//处理左边的
if (position <= 0) {
page.alpha =
0.5f + 0.5f * (1 + position)
} else { // 处理右边
page.alpha =
0.5f + 0.5f * (1 - position)
}
val scale = 0.8f.coerceAtLeast(1 - abs(position))
page.scaleX = scale
page.scaleY = scale
}
}
层叠效果
private class AlphaMode : ViewPager2.PageTransformer {
override fun transformPage(page: View, position: Float) {
val pageWidth: Int = page.width
val transX = if (position > 0) -pageWidth * position else pageWidth * position
page.translationX = transX
page.translationZ = -position
if (position > 1 || position < -1) {
page.alpha = 0f
page.scaleY = 0f
page.scaleX = 0f
return
}
val scale = 1 - position * 0.7f
page.scaleX = scale
page.scaleY = scale
page.alpha = 1 - abs(position - position.toInt())
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)