RecyclerView实现抖音纵向滚动ViewPager效果

所属分类: 软件编程 / Android 阅读数: 96
收藏 0 赞 0 分享

使用RecyclerView实现抖音纵向滚动ViewPager效果,供大家参考,具体内容如下

重写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)
  }

}

代码参考:LayoutManagerGroup

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多精彩内容其他人还在看

Android样式和主题之选择器的实例讲解

今天小编就为大家分享一篇关于Android样式和主题之选择器的实例讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
收藏 0 赞 0 分享

Android应用动态修改主题的方法示例

今天小编就为大家分享一篇关于Android应用动态修改主题的方法示例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
收藏 0 赞 0 分享

Flutter 网络请求框架封装详解

这篇文章主要介绍了Flutter 网络请求框架封装详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Flutter倒计时/计时器的实现代码

这篇文章主要介绍了Flutter倒计时/计时器的实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

Android使用google breakpad捕获分析native cash

这篇文章主要介绍了Android使用google breakpad捕获分析native cash 的相关知识,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

详解Flutter WebView与JS互相调用简易指南

这篇文章主要介绍了详解Flutter WebView与JS互相调用简易指南,分为JS调用Flutter和Flutter调用JS,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Android开发实现ListView和adapter配合显示图片和文字列表功能示例

这篇文章主要介绍了Android开发实现ListView和adapter配合显示图片和文字列表功能,涉及Android使用ListView结合adapter适配器实现图文显示功能相关的布局、解析、权限控制等操作技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

Android文字基线Baseline算法的使用讲解

今天小编就为大家分享一篇关于Android文字基线Baseline算法的使用讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
收藏 0 赞 0 分享

Flutter自定义实现神奇动效的卡片切换视图的示例代码

这篇文章主要介绍了Flutter自定义实现神奇动效的卡片切换视图的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Android实现自定义滑动刻度尺方法示例

这篇文章主要给大家介绍了关于Android实现自定义滑动刻度尺的相关资料,文中通过示例代码介绍的非常详细,对各位Android开发者们具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
收藏 0 赞 0 分享
查看更多