recyclerview 优雅的解决监听滑动和暂停的显示隐藏动画

一、监听recyclerview 滑动中和暂停 重复调用之 烦恼

直接上图:

2021-02-07 15.30.39.gif

代码如下:

private fun initRvView() {
        rv_content.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
        rv_content.adapter = TestAdapter(this)

        val itemDecoration = DividerItemDecoration(this, RecyclerView.VERTICAL)
        itemDecoration.setDrawable(ColorDrawable(Color.parseColor("#333333")))
        rv_content.addItemDecoration(itemDecoration)
        rv_content.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState)


                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    animToLeft()
                } else {
                    animToRight()
                }


            }
        })

    }/**
     * 向右移动 动画
     */
    private fun animToRight() {

        val toRightAnim = TranslateAnimation(0f, 400f, 0f, 0f)
        toRightAnim.duration = 200
        toRightAnim.fillAfter = true

        tv_anim_target.startAnimation(toRightAnim)

    }
    /**
     * 向左移动 动画  出来动画
     */
    private fun animToLeft() {

        val toLeftAnim = TranslateAnimation(400f, 0f, 0f, 0f)
        toLeftAnim.duration = 200
        toLeftAnim.fillAfter = true

        tv_anim_target.startAnimation(toLeftAnim)
    }

动画效果如图所示,在快速的连续的滑动过程中,动画会频繁的闪动。原因是SCROLL_STATE_DRAGGING=1
和SCROLL_STATE_SETTLING=2 这两个转态会频繁的触发。而SCROLL_STATE_IDLE=0这个状态最后才会触发。

为了解决这个问题,也只能是屏蔽掉,重复的这两个状态。正常处理逻辑代码如下:


if (newState==RecyclerView.SCROLL_STATE_IDLE&&mLastState!=RecyclerView.SCROLL_STATE_IDLE){
                    animToLeft()
                }else if ((newState==RecyclerView.SCROLL_STATE_DRAGGING|| newState==RecyclerView.SCROLL_STATE_SETTLING)&&(mLastState!=RecyclerView.SCROLL_STATE_DRAGGING&&mLastState!=RecyclerView.SCROLL_STATE_SETTLING)){
                    animToRight()
                }

虽然没啥毛病,但是这逻辑写的也太狗屎了吧。

最后想了好久:最终使用rxjava 来优雅的解决这个问题。
代码如下:


    private fun initRvView() {


        Flowable.create(object : FlowableOnSubscribe {
            override fun subscribe(e: FlowableEmitter) {

                mEmmiter = e
            }
        }, BackpressureStrategy.BUFFER)
                .map {
                    return@map it > 0
                }
                .distinctUntilChanged()
                .subscribe(Consumer { isIdle ->

                    if (isIdle) {
                        animToRight()

                    } else {

                        animToLeft()
                    }
                })


        rv_content.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
        rv_content.adapter = TestAdapter(this)

        val itemDecoration = DividerItemDecoration(this, RecyclerView.VERTICAL)
        itemDecoration.setDrawable(ColorDrawable(Color.parseColor("#333333")))
        rv_content.addItemDecoration(itemDecoration)
        rv_content.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState)

                mEmmiter.onNext(newState)



            }
        })

    }

修改之后的动画效果,顿时流畅了很多:


after_anim.gif

结论: 有时候在正常编码过程中 业务逻辑做起来确实很恶心。但是当你将这种业务场景转换成rx 流式编程的思想,然后使用功能强大的操作符,那么问题就会变得很简单容易处理

你可能感兴趣的:(recyclerview 优雅的解决监听滑动和暂停的显示隐藏动画)