1 view的生命周期回调流程(按照调用顺序)
- 构造函数
-
如果是在layout中定义,则会走到两个参数的构造函数:CounterView(Context context, @Nullable AttributeSet attrs)。
-
如果是在代码中直接new,则走到一个参数的构造函数。
- onVisibilityChanged()
可见性不是默认值(即可见)时调用。 - onFinishInflate()
该方法当View及其子View从XML文件中加载完成后会被调用。 - onAttachedToWindow()
- 绑定到对应的window;
- 如果可见性为gone,则走到这里生命周期结束;
- onMeasure()
计算当前View及其所有子View尺寸大小。 - onSizeChanged()
当前View尺寸变化时被调用。 - onLayout()
-
当前View需要为其子View分配尺寸和位置时会被调用。
-
若View是invisible,则View的创建生命周期结束。
-
onWindowFocusChanged
当前View的window获得或失去焦点时被调用。 -
onDraw()
只有可见的view才会在window中绘制。
10.onDetachedFromWindow()
注意:
5、7、9可能会被多次调用;
2 调用顺序图
View生命周期图.png-
为什么Constructor会出现两次?
构造函数.png
调用顺序.png
从setContentView开始,inflate解析XML,通过反射构造View,走到super(context,attrs),在其中有可能调用onVisiablityChanged()方法,然后接着调用super(context,attrs)之后的代码进行初始化。
3 实例
activity与view的生命周期图.png4 实践
3.1 执行动画的时机
如果view中需要注册监听,开始执行某动画效果,可以在onAttachedToWindow中开始执行动画。
3.2 view.post(runnable)
-
什么时候被调用?
如果调用时,mAttachInfo已经有值(onAttachToWindow()调用之后才赋值成功),则直接调用mAttachInfo中的mHandler。
如果还没被赋值,则该runnable会被暂存在RunQueue中。最终会在performTraversals()函数中取出并放到主线程handler中,等待被主线程执行。在第一次measure、layout过程结束之后会执行,所以可以获取到view 的宽高。
performTraversals.png -
注意
如果在onCreate()中的子线程去调用,很有可能不被执行。因为此时还未调用onAttachedToWindow,该runnable会被暂存在RunQueue中。而RunQueue是一个ThreadLocal类型的变量,所以,你懂的。
RunQueue.png
网友评论