• RecyclerView+PageSnapHelper实现ViewPager效果+自动翻页


    预期效果是大多app都会用到的首页顶部图片banner,3s自动轮播,也可手动切换

    用法很简单,做attach就好(以下为kotlin代码)

    recyclerView.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
    val snapHelper = PagerSnapHelper()
    snapHelper.attachToRecyclerView(recyclerView)

    自动翻页是定义的handler每3s执行一次bannerPos++然后recyclerView滚动,但是注意滚动的方法要使用

    recyclerView.smoothScrollToPosition(bannerPos)

    使用的话scrollToPosition()就不会有左右平滑的效果

    如果需要同步更新Indicator,在recyclerView的滑动监听里

    recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
                        override fun onScrollStateChanged(recycler: RecyclerView, newState: Int) {
                            super.onScrollStateChanged(recycler, newState)
                            when (newState) {
                                RecyclerView.SCROLL_STATE_IDLE -> {
                                    val viewIdle = snapHelper.findSnapView(recyclerView.layoutManager)
                                    if (viewIdle != null) {
                                        val pos = recyclerView.layoutManager?.getPosition(viewIdle) ?: 0
                                        updateIndicators(pos)
                                    }
                                }
                            }
                        }
                    })
      /**
         * 更新到当前指示器
         */
        private fun updateIndicators(position: Int) {
            for (i in 0 until indicatorContainer.childCount) {
                val childView = indicatorContainer.getChildAt(i)
                childView.background = if (position == i)
                   resources.getDrawable(R.drawable.shape_indicator_orange)
                else
                   resources.getDrawable(R.drawable.shape_indicator_gray)
            }
        }

    补充一下indicator的初始化方法

    private fun setIndicators(bannerList: List<String>?) {
            //只有一页的时候不显示指示器
            if (bannerList?.size ?: 0 <= 1) {
                return
            }
            indicatorContainer.removeAllViews()
            for (i in bannerList!!.indices) {
                val indicatorView = View(context)
                indicatorView.background = resources.getDrawable(R.drawable.shape_indicator_gray)
                val layoutParams: LinearLayout.LayoutParams = LinearLayout.LayoutParams(
                    ConvertUtils.dp2px(6f), ConvertUtils.dp2px(6f)
                )
                if (i != 0) layoutParams.leftMargin = ConvertUtils.dp2px(8f)
                indicatorView.layoutParams = layoutParams
                indicatorContainer.addView(indicatorView)
            }
            updateIndicators(indicatorContainer, 0)
        }

    我这里把整个页面都用一个recyclerView展示的,所以顶部banner也作为一个item嵌在数据里(感觉还是addHeader方法合理哈),嵌套在里面要更新呢就更新adapter,当时发现自动翻页时滑动起来有重复页面闪过的情况,这是因为adapter做notify的时候每次都重置到了第一页再调用前面说的smooth方法滑动,所以中间页面会展示出快速划过。

    所以我在调用smooth滑动之前先把banner用scrollToPosition()方法无痕迹滑动到前一张,这样就看不出闪页了

    if (bannerPos > 0){
        recyclerView.scrollToPosition(bannerPos-1)
    }
  • 相关阅读:
    Linux Shell处理文本最常用的工具大盘点
    Linux GCC常用命令
    IT运维流程 — ITIL
    linux软件安装与卸载
    ifconfig无输出的解决办法
    du 命令秘籍
    linux主机名的修改
    输错密码?这个 sudo 会“嘲讽”你
    VS开发环境美化
    oracle +plsql装完省略号不能点
  • 原文地址:https://www.cnblogs.com/Sharley/p/15153164.html
Copyright © 2020-2023  润新知