Android:ViewPager2制作一个一屏多Item的轮播图

Android:ViewPager2制作一个一屏多Item的轮播图,第1张

具体思路是利用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())
        }
    }

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/992242.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存