View的生命周期及实践

1 view的生命周期回调流程(按照调用顺序)

  1. 构造函数
  • 如果是在layout中定义,则会走到两个参数的构造函数:CounterView(Context context, @Nullable AttributeSet attrs)。

  • 如果是在代码中直接new,则走到一个参数的构造函数。

  1. onVisibilityChanged()
    可见性不是默认值(即可见)时调用。
  2. onFinishInflate()
    该方法当View及其子View从XML文件中加载完成后会被调用。
  3. onAttachedToWindow()
  • 绑定到对应的window;
  • 如果可见性为gone,则走到这里生命周期结束;
  1. onMeasure()
    计算当前View及其所有子View尺寸大小。
  2. onSizeChanged()
    当前View尺寸变化时被调用。
  3. onLayout()
  • 当前View需要为其子View分配尺寸和位置时会被调用。

  • 若View是invisible,则View的创建生命周期结束。

  1. onWindowFocusChanged
    当前View的window获得或失去焦点时被调用。

  2. 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的生命周期图.png

4 实践

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
ViewRootImpl.getRunQueue.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容