美文网首页Android开发Android开发经验谈Android技术知识
RecyclerView实现垂直自动无限滚动,类似于中奖信息,跑

RecyclerView实现垂直自动无限滚动,类似于中奖信息,跑

作者: kermitye | 来源:发表于2018-10-11 18:29 被阅读49次

    RecyclerView实现垂直自动无限滚动,类似于中奖信息,跑马灯

    实现RecyclerView中的效果有两种:

    一种为以item为单体,每隔多少秒进行滚动一次

    一种为整体流形式进行缓慢滚动

    item为单位进行滚动 流形式进行滚动

    实现无限滚动

    这里实现无限滚动的方式为在adpater中设置itemCount为 Integer.MAX_VALUE

    注意:此处基于BaseQuickAdapter的库进行的,也可直接使用原生

    class MainAdatper(data: List<String>) : BaseQuickAdapter<String, BaseViewHolder>(R.layout.item_txt, data) {
    
        override fun convert(helper: BaseViewHolder?, item: String?) {
            helper?.setText(R.id.mTv, item)
        }
    
    
        override fun getItem(position: Int): String? {
            val newPosition = position % data.size
            return getData().get(newPosition)
        }
    
        override fun getItemViewType(position: Int): Int {
            var count = getHeaderLayoutCount() + getData().size
            //刚开始进入包含该类的activity时,count为0。就会出现0%0的情况,这会抛出异常,所以我们要在下面做一下判断
            if (count <= 0) {
                count = 1
            }
            var newPosition = position % count;
            return super.getItemViewType(newPosition);
        }
    
        override fun getItemCount(): Int {
            return Integer.MAX_VALUE
        }
    
    }
    

    item为单位,每隔n秒滚动一个item

    这边主要是使用recyclerView中的smoothScrollToPosition() 方法实现,然后再配合自定义layoutManager 控制速度达到目的效果

    var layoutManager = object : LinearLayoutManager(this) {
        override fun smoothScrollToPosition(recyclerView: RecyclerView?, state: RecyclerView.State?, position: Int) {
            var linearSmoothScroller = object : LinearSmoothScroller(recyclerView?.context) {
    
                //返回滑动一个pixel需要多少毫秒
                override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics?): Float {
                    //这边可以自定义进行控制速度
                    return 3f / (displayMetrics?.density ?: 1f)
                }
            }
            linearSmoothScroller.setTargetPosition(position)
            startSmoothScroll(linearSmoothScroller)
        }
    }
    
    mRv.layoutManager = layoutManager
    mRv.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))
    mRv.adapter = MainAdatper(data)
    
    
    
    ==============================================================
    fun startAuto() {
        if (mAutoTask != null && (mAutoTask?.isDisposed ?: true))
            mAutoTask?.dispose()
        
        //此处的4为当前显示的最后一个item
        mAutoTask = Observable.interval(1, 2, TimeUnit.SECONDS).subscribe {
            mRv.smoothScrollToPosition((4 + it).toInt())
        }
    }
    
    fun stopAuto() {
        if (mAutoTask != null && (mAutoTask?.isDisposed ?: true)) {
            mAutoTask?.dispose()
            mAutoTask = null
        }
    }
    
    
    override fun onStart() {
        super.onStart()
        //开始滚动
        startAuto()
    }
    
    override fun onStop() {
        super.onStop()
        //停止滚动
        stopAuto()
    }
    
    

    流式滚动

    流式滚动是使用recyclerView中的 smoothScrollBy(x, y) 方法来实现的

    此处是通过自定义recyclerView来进行实现,也可直接在activity中进行实现。

    class AutoScrollRecyclerView(mContext: Context, attrs: AttributeSet?) : RecyclerView(mContext, attrs) {
    
        private var mAutoTask: Disposable? = null
    
        //禁止手动滑动
        override fun onTouchEvent(e: MotionEvent): Boolean {
            return true
        }
    
        fun start() {
            if (mAutoTask != null && !mAutoTask!!.isDisposed) {
                mAutoTask!!.dispose()
            }
            mAutoTask = Observable.interval(1000, 100, TimeUnit.MILLISECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe { smoothScrollBy(0, 20) }
        }
    
        fun stop() {
            if (mAutoTask != null && !mAutoTask!!.isDisposed) {
                mAutoTask!!.dispose()
                mAutoTask = null
            }
        }
    
    }
    
    ==================================================
    //在activity中调用开始滚动与停止滚动
    override fun onStart() {
        super.onStart()
        mRvTwo.start()
    }
    
    override fun onStop() {
        super.onStop()
        mRvTwo.stop()
    }
        
    

    项目地址

    相关文章

      网友评论

      • 周晓川:我运行你的demo在我的手机上,在以item为滚动单位的时候,会出现上下来回滚动紊乱的情况。
      • 周晓川:老哥抽个时间帮忙解决下那个异常呗。
        周晓川:@kermitye 老哥,你能不能转成java项目看一下这个问题。我在adapter的getItemViewType()中处理这个count,要么就是继续异常,要么就是第一次数据滚动完之后,后面的就不滚动了,显示一片空白。
        kermitye:既然找到了问题所在,就好办了。
        断点找下newPosition会等于数组长度的原因
        是count导致或者是data的size引起的
        因为我这边并没有出现此异常,不好判断
      • 周晓川:我按照你的思路,将你的kotlin项目转成了java项目,运行滚动几条之后就会报下标越界异常。( java.lang.IndexOutOfBoundsException: Index: 15, Size: 15)请问该如何处理?
        kermitye:@周晓川 那检查一下adpter中重写的getItem及getItemViewType方法中的逻辑,通过计算得出的newPosition是否出现了越界的情况
        周晓川:@kermitye 设置的是Integer.MAX_VALUE,我的adapter也是继承自BaseQuickAdapter。我仔细观察了一下,是滚动到最后一个itme后切换到第一个item的时候就会出现这个异常。
        kermitye:查看下你的adapter中返回的条目数是否设置为Integer.MAX_VALUE

      本文标题:RecyclerView实现垂直自动无限滚动,类似于中奖信息,跑

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