一、监听recyclerview 滑动中和暂停 重复调用之 烦恼
直接上图:
代码如下:
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)
}
})
}
修改之后的动画效果,顿时流畅了很多:
结论: 有时候在正常编码过程中 业务逻辑做起来确实很恶心。但是当你将这种业务场景转换成rx 流式编程的思想,然后使用功能强大的操作符,那么问题就会变得很简单容易处理