zoukankan      html  css  js  c++  java
  • 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)
    }
  • 相关阅读:
    《理解 ES6》阅读整理:块绑定(Block Binding)
    Webpack使用教程六(Plugins)
    Webpack使用教程五(Babel)
    Webpack使用教程四(Loaders)
    Webpack使用教程三(webpack-dev-server)
    Webpack使用教程二
    Node.js、npm和webpack的安装
    Maven的安装和配置
    Java事件处理机制
    MySQL安装
  • 原文地址:https://www.cnblogs.com/Sharley/p/15153164.html
Copyright © 2011-2022 走看看