文章目录
- 一、在RecyclerView的Item的onBindViewHolder时,利用一个CountDownTimer去做一个倒计时显示 / 或者是有一个属性动画效果?
- 二、onAttachedToWindow和onDetachedFromWindow调用时机
- 2.1、onAttachedToWindow中能否取得View的宽高
- 三、相关文章
一、在RecyclerView的Item的onBindViewHolder时,利用一个CountDownTimer去做一个倒计时显示 / 或者是有一个属性动画效果?
到底在什么时候可以cancel掉这个倒计时/ 动画,而不影响功能了(滑动到用户可见范围内,倒计时/动画 运作正常)?
有什么方法可以和onBindViewHolder
对应吗?就像onAttachedToWindow
,onDetachedFromWindow
这样 。
-
onAttachedToWindow
和onDetachedFromWindow
在RecyclerView
中还适用吗?
在RecyclerView
中,Item
的这两个方法分别会在【首次出现】和【完全滑出屏幕】(即在屏幕中完全不可见)时回调(在Adapter
中也可以重写同名方法,用来监听ViewHolder
的出现和消失)。
至于说适不适用,还是看具体需求,比如列表中的视频播放,在onDetachedFromWindow
回调时暂停/停止还是合理的。
但是像题目说的倒计时和属性动画效果,就不合适了,为什么呢?
我们先粗略地温习一下RecyclerView
的回收机制:
RecyclerView
在布局(自然滑动其实也是反复布局子View
)时,会回收一些符合条件的ViewHolder
,它会根据ViewHolder
的状态来决定临时存放在哪个地方,且把这些临时存放ViewHolder
的集合看作两种:
不需要经过onBindViewHolder
能直接重用的(mAttachedScrap、mCachedViews
);
需要经过onBindViewHolder
重新绑定数据的(mRecyclerPool.mScrap
);mAttachedScrap
,正常情况下,它会在RecyclerView
每次布局时都用到:在布局子View
时,会把全部子View
所属的Holder
,都临时放里面,计算好了每个子View
的新位置后,会一个个从mAttachedScrap
中取出来,当然了不一定是全部都会取出来的,因为可能本次布局,一些旧Item
已经完全滑出屏幕了。
- 那么,这些留在
mAttachedScrap
中没有被取出来的ViewHolder
会怎么样呢?
正常情况下,它们会被扔到mCachedViews
里面去(注意从mCachedViews
中取出来时也是不用重新绑定数据的,即不会经过onBindViewHolder
方法)。
刚刚说过,当Item
被完全滑出屏幕时,Adapter
的onDetachedFromWindow
和该Item
的onDetachedFromWindow
会被回调,也就是说,当onDetachedFromWindow
被回调时,ViewHolder
并没有真正被回收!如果这时候把倒计时/动画取消掉了,那么在它们再次出现在屏幕中的时候,就不会动了,因为是直接重用,不会重新绑定数据的。
- 那应该在什么时候取消?
Adapter
中有个onViewRecycled
方法,看名字就知道是当Item
被回收后回调的。。。
没错了,这个方法回调时,表示这个Holder
已经被扔进mRecyclerPool.mScrap
里了,也就是再次取出的时候会经过onBindViewHolder
方法重新绑定数据。
倒计时/动画在这里取消的话,是完全没问题的(但记得保存当前进度,以便下次恢复)。
所以与onBindViewHolder
对应的方法,就是这个onViewRecycled
了。
有同学可能会说:我不见得非要在onViewRecycled
方法中取消才能正常运作,我在onDetachedFromWindow
中取消,在onAttachedToWindow
恢复,不行吗?
可以是可以。。。但你这不是多做了事情了嘛,人家onBindViewHolder
本来就已经承担了恢复的工作了。。。
二、onAttachedToWindow和onDetachedFromWindow调用时机
1、onAttachedToWindow
调用顺序:ActivityThread.handleResumeActivity->WindowManagerImpl.addView->WindowManagerGlobal.addView->ViewRootImpl.performTraversals->ViewGroup.dispatchAttachedToWindow->View.dispatchAttachedToWindow->onAttachedToWindow
2、onDetachedFromWindow
调用顺序:ActivityThread.handleDestroyActivity->WindowManagerImpl.removeViewImmediate->WindowManagerGlobal.removeView->ViewRootImpl.die->ViewRootImpl.doDie->ViewRootImpl.dispatchDetachedFromWindow->ViewGroup.dispatchDetachedFromWindow->View.dispatchDetachedFromWindow->onDetachedToWindow
3、onAttachedToWindow
和onDetachedFromWindow
的调用与visibility
无关。
4、onAttachedToWindow
是先调用自己,然后调用儿子View
的。onDetachedFromWindow
是先调用儿子View
的,然后再调用自己的。
2.1、onAttachedToWindow中能否取得View的宽高
onAttachedToWindow()
里并不能拿到View
的宽高信息的,可以通过View.post
来获取宽高信息。
【1】每日一问:浅谈 onAttachedToWindow 和 onDetachedFromWindow 【2】onAttachedToWindow和onDetachedFromWindow调用时机源码解析