美文网首页Android开发知识小集Android-RecyclerView
使用RecyclerView实现抖音纵向滚动ViewPager效

使用RecyclerView实现抖音纵向滚动ViewPager效

作者: TomCat0916 | 来源:发表于2018-08-24 10:49 被阅读274次

    重写LinearLayoutManager,在onAttachedToWindow方法中使用 PagerSnapHelper设置RecyclerView条目加载方式为每次滚动加载一页

    class MyLinearLayoutManager : LinearLayoutManager {
    
        private lateinit var mPagerSnapHelper: PagerSnapHelper
        private var mOnViewPagerListener: OnViewPagerListener? = null
        private lateinit var mRecyclerView: RecyclerView
        private var mDrift: Int = 0//位移,用来判断移动方向
    
        constructor(context: Context) : this(context, OrientationHelper.VERTICAL)
        constructor(context: Context, orientation: Int) : this(context, orientation, false)
        constructor(context: Context, orientation: Int, reverseLayout: Boolean) : super(context, orientation, reverseLayout) {
            mPagerSnapHelper = PagerSnapHelper()
        }
    
        override fun onAttachedToWindow(view: RecyclerView) {
            super.onAttachedToWindow(view)
            mPagerSnapHelper.attachToRecyclerView(view)//设置RecyclerView每次滚动一页
            mRecyclerView = view
            mRecyclerView.addOnChildAttachStateChangeListener(mChildAttachStateChangeListener)
        }
    
    
        /**
         * 滑动状态的改变
         * 缓慢拖拽-> SCROLL_STATE_DRAGGING
         * 快速滚动-> SCROLL_STATE_SETTLING
         * 空闲状态-> SCROLL_STATE_IDLE
         * @param state
         */
        override fun onScrollStateChanged(state: Int) {
            if (state == RecyclerView.SCROLL_STATE_IDLE){
                val viewIdle = mPagerSnapHelper.findSnapView(this)
                val positionIdle = getPosition(viewIdle!!)
                if (mOnViewPagerListener != null && childCount == 1) {
                    mOnViewPagerListener!!.onPageSelected(positionIdle, positionIdle == itemCount - 1)
                }
            }
        }
    
        /**
         * 布局完成后调用
         * @param state
         */
        override fun onLayoutCompleted(state: RecyclerView.State?) {
            super.onLayoutCompleted(state)
            if (mOnViewPagerListener != null) mOnViewPagerListener!!.onLayoutComplete()
        }
    
        /**
         * 监听竖直方向的相对偏移量
         */
        override fun scrollVerticallyBy(dy: Int, recycler: RecyclerView.Recycler?, state: RecyclerView.State?): Int {
            this.mDrift = dy
            return super.scrollVerticallyBy(dy, recycler, state)
        }
    
    
        /**
         * 监听水平方向的相对偏移量
         */
        override fun scrollHorizontallyBy(dx: Int, recycler: RecyclerView.Recycler?, state: RecyclerView.State?): Int {
            this.mDrift = dx
            return super.scrollHorizontallyBy(dx, recycler, state)
        }
    
        /**
         * 设置监听
         * @param listener
         */
        fun setOnViewPagerListener(listener: OnViewPagerListener) {
            this.mOnViewPagerListener = listener
        }
    
        private val mChildAttachStateChangeListener = object : RecyclerView.OnChildAttachStateChangeListener {
            override fun onChildViewAttachedToWindow(view: View) {
            }
    
            override fun onChildViewDetachedFromWindow(view: View) {
                if (mDrift >= 0) {
                    if (mOnViewPagerListener != null) mOnViewPagerListener!!.onPageRelease(true, getPosition(view))
                } else {
                    if (mOnViewPagerListener != null) mOnViewPagerListener!!.onPageRelease(false, getPosition(view))
                }
    
            }
        }
    
        interface OnViewPagerListener{
            /*释放的监听*/
            fun onPageRelease(isNext: Boolean, position: Int)
    
            /*选中的监听以及判断是否滑动到底部*/
            fun onPageSelected(position: Int, isBottom: Boolean)
    
            /*布局完成的监听*/
            fun onLayoutComplete()
        }
    }
    

    重写RecyclerView条目内容主布局满屏填充

    class MyImageView : ImageView {
        constructor(context: Context) : this(context, null!!)
        constructor(context: Context, attr: AttributeSet) : this(context, attr, 0)
        constructor(context: Context, attr: AttributeSet, defStyleAttr: Int) : super(context, attr, defStyleAttr)
    
        override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
            val width = View.getDefaultSize(0, widthMeasureSpec)
            val height = View.getDefaultSize(0, heightMeasureSpec)
            setMeasuredDimension(width, height)
        }
    
    }
    

    代码参考:https://github.com/DingMouRen/LayoutManagerGroup

    相关文章

      网友评论

        本文标题:使用RecyclerView实现抖音纵向滚动ViewPager效

        本文链接:https://www.haomeiwen.com/subject/yvkbiftx.html