View/ViewGroup的生命周期
View是什么?官方源码注释中的定义:这个类是用户接口的基础构件。View表示屏幕上的一块矩形区域,负责绘制这个区域和事件处理。
View是所有widget类的基类,Widget类用于创建交互式UI构件(按钮,输入框等)。
View类的ViewGroup子类是layout的基类,Layout是一个不可见的容器,它保存着View(或ViewGroup)并定义这些View的layout 属性。
简单点说,View就是屏幕上的一块矩形区域,我们可以在这块区域绘制我们想让用户看到的图形。
关于View的生命周期,官方源码注释中有详细的描述,作为英语六级勉强飘过的选手,我顶着巨大的压力翻译了一下。
Creation(创建)
Constructors(构造函数):有一种形式的构造函数会在View在代码中被创建时调用,另一种形式的构造函数会在View从layout加载出来时被调用。
第二种形式的构造函数会解析和应用layout文件中定义的任何属性。
onFinishInflate():该方法当View及其子View从XML文件中加载完成后会被调用。
Layout(布局)
onMeasure(int, int):该方法在计算当前View及其所有子View尺寸大小需求时会被调用。
onLayout(boolean, int, int, int, int):该方法在当前View需要为其子View分配尺寸和位置时会被调用。
onSizeChanged(int, int, int, int):该方法在当前View尺寸变化时被调用。
Drawing(绘制)
onDraw(android.graphics.Canvas):该方法在当前View需要呈现其内容时被调用。
Event processing(事件处理)
onKeyDown(int, KeyEvent):该方法在一个物理按键事件发生时被调用。
onKeyUp(int, KeyEvent):该方法在一个物理按键弹起事件发生时被调用。
onTrackballEvent(MotionEvent):该方法在一个轨迹球运动事件发生时被调用。
onTouchEvent(MotionEvent):该方法在一个触摸屏幕运动事件发生时被调用。
Focus(聚焦)
onFocusChanged(boolean, int, android.graphics.Rect):该方法在当前View获得或失去焦点时被调用。
onWindowFocusChanged(boolean):该方法在包含当前View的window获得或失去焦点时被调用。
Attaching(附上)
onAttachedToWindow():该方法在当前View被附到一个window上时被调用。
onDetachedFromWindow():该方法在当前View从一个window上分离时被调用。
onVisibilityChanged(View, int):该方法在当前View或其祖先的可见性改变时被调用。
onWindowVisibilityChanged(int):该方法在包含当前View的window可见性改变时被调用。
上述方法是View生命周期中涉及到的比较重要的一部分,View类中包含了很多的方法和属性,有兴趣的话各位可以自己研究一下。
View生命周期相关方法调用顺序
简单的了解了View生命周期相关的几个方法,接着我们看看这些方法调用的顺序是怎样的,我们针对View的可见性分三种情况来观察。
1.android:visibility=visible
创建
I/TestView: TestView(Context context, AttributeSet attrs)
I/TestView: onFinishInflate()
I/TestView: onVisibilityChanged(View changedView, int visibility) changedView = com.android.internal.policy.impl.PhoneWindow$DecorView{2192bad9 I.E..... R.....ID 0,0-0,0} visibility = 4
I/TestView: onVisibilityChanged(View changedView, int visibility) changedView = com.android.internal.policy.impl.PhoneWindow$DecorView{2192bad9 V.E..... R.....ID 0,0-0,0} visibility = 0
I/TestView: onAttachedToWindow()
I/TestView: onWindowVisibilityChanged(int visibility) visibility = 0
I/TestView: onMeasure(int widthMeasureSpec, int heightMeasureSpec) widthMeasureSpec = 1073743152 heightMeasureSpec = 1073743848
I/TestView: onMeasure(int widthMeasureSpec, int heightMeasureSpec) widthMeasureSpec = 1073743152 heightMeasureSpec = 1073743848
I/TestView: onMeasure(int widthMeasureSpec, int heightMeasureSpec) widthMeasureSpec = 1073743152 heightMeasureSpec = 1073744016
I/TestView: onMeasure(int widthMeasureSpec, int heightMeasureSpec) widthMeasureSpec = 1073743152 heightMeasureSpec = 1073744016
I/TestView: onSizeChanged(int w, int h, int oldw, int oldh) w = 1328 h = 2192 oldw = 0 oldh0
I/TestView: onLayout(boolean changed, int left, int top, int right, int bottom) changed = true left = 56 top = 56 right = 1384 bottom = 2248
I/TestView: onMeasure(int widthMeasureSpec, int heightMeasureSpec) widthMeasureSpec = 1073743152 heightMeasureSpec = 1073743820
I/TestView: onSizeChanged(int w, int h, int oldw, int oldh) w = 1328 h = 1996 oldw = 1328 oldh2192
I/TestView: onLayout(boolean changed, int left, int top, int right, int bottom) changed = true left = 56 top = 56 right = 1384 bottom = 2052
I/TestView: onDraw(Canvas canvas)
I/TestView: onWindowFocusChanged(boolean hasWindowFocus) hasWindowFocus = true
I/TestView: onMeasure(int widthMeasureSpec, int heightMeasureSpec) widthMeasureSpec = 1073743152 heightMeasureSpec = 1073743820
I/TestView: onMeasure(int widthMeasureSpec, int heightMeasureSpec) widthMeasureSpec = 1073743152 heightMeasureSpec = 1073743820
I/TestView: onLayout(boolean changed, int left, int top, int right, int bottom) changed = false left = 56 top = 56 right = 1384 bottom = 2052
I/TestView: onDraw(Canvas canvas)
销毁
I/TestView: onWindowFocusChanged(boolean hasWindowFocus) hasWindowFocus = false
I/TestView: onWindowVisibilityChanged(int visibility) visibility = 8
I/TestView: onDetachedFromWindow()
2.android:visibility=invisible
创建
I/TestView: onVisibilityChanged(View changedView, int visibility) changedView = com.example.junyizhou.rxjavademo.TestView{3ead3d52 I.ED.... ........ 0,0-0,0} visibility = 4
I/TestView: TestView(Context context, AttributeSet attrs)
I/TestView: onFinishInflate()
I/TestView: onVisibilityChanged(View changedView, int visibility) changedView = com.android.internal.policy.impl.PhoneWindow$DecorView{3aeb2b95 I.E..... R.....ID 0,0-0,0} visibility = 4
I/TestView: onVisibilityChanged(View changedView, int visibility) changedView = com.android.internal.policy.impl.PhoneWindow$DecorView{3aeb2b95 V.E..... R.....ID 0,0-0,0} visibility = 0
I/TestView: onAttachedToWindow()
I/TestView: onWindowVisibilityChanged(int visibility) visibility = 0
I/TestView: onMeasure(int widthMeasureSpec, int heightMeasureSpec) widthMeasureSpec = 1073743152 heightMeasureSpec = 1073743848
I/TestView: onMeasure(int widthMeasureSpec, int heightMeasureSpec) widthMeasureSpec = 1073743152 heightMeasureSpec = 1073743848
I/TestView: onMeasure(int widthMeasureSpec, int heightMeasureSpec) widthMeasureSpec = 1073743152 heightMeasureSpec = 1073744016
I/TestView: onMeasure(int widthMeasureSpec, int heightMeasureSpec) widthMeasureSpec = 1073743152 heightMeasureSpec = 1073744016
I/TestView: onSizeChanged(int w, int h, int oldw, int oldh) w = 1328 h = 2192 oldw = 0 oldh0
I/TestView: onLayout(boolean changed, int left, int top, int right, int bottom) changed = true left = 56 top = 56 right = 1384 bottom = 2248
I/TestView: onMeasure(int widthMeasureSpec, int heightMeasureSpec) widthMeasureSpec = 1073743152 heightMeasureSpec = 1073743820
I/TestView: onSizeChanged(int w, int h, int oldw, int oldh) w = 1328 h = 1996 oldw = 1328 oldh2192
I/TestView: onLayout(boolean changed, int left, int top, int right, int bottom) changed = true left = 56 top = 56 right = 1384 bottom = 2052
I/TestView: onWindowFocusChanged(boolean hasWindowFocus) hasWindowFocus = true
I/TestView: onMeasure(int widthMeasureSpec, int heightMeasureSpec) widthMeasureSpec = 1073743152 heightMeasureSpec = 1073743820
I/TestView: onMeasure(int widthMeasureSpec, int heightMeasureSpec) widthMeasureSpec = 1073743152 heightMeasureSpec = 1073743820
I/TestView: onLayout(boolean changed, int left, int top, int right, int bottom) changed = false left = 56 top = 56 right = 1384 bottom = 2052
销毁
I/TestView: onWindowFocusChanged(boolean hasWindowFocus) hasWindowFocus = false
I/TestView: onWindowVisibilityChanged(int visibility) visibility = 8
I/TestView: onDetachedFromWindow()
3.android:visibility=gone
创建
I/TestView: onVisibilityChanged(View changedView, int visibility) changedView = com.example.junyizhou.rxjavademo.TestView{3ead3d52 G.ED.... ......I. 0,0-0,0} visibility = 8
I/TestView: TestView(Context context, AttributeSet attrs)
I/TestView: onFinishInflate()
I/TestView: onVisibilityChanged(View changedView, int visibility) changedView = com.android.internal.policy.impl.PhoneWindow$DecorView{3aeb2b95 I.E..... R.....ID 0,0-0,0} visibility = 4
I/TestView: onVisibilityChanged(View changedView, int visibility) changedView = com.android.internal.policy.impl.PhoneWindow$DecorView{3aeb2b95 V.E..... R.....ID 0,0-0,0} visibility = 0
I/TestView: onAttachedToWindow()
I/TestView: onWindowVisibilityChanged(int visibility) visibility = 0
I/TestView: onWindowFocusChanged(boolean hasWindowFocus) hasWindowFocus = true
销毁
I/TestView: onWindowFocusChanged(boolean hasWindowFocus) hasWindowFocus = false
I/TestView: onWindowVisibilityChanged(int visibility) visibility = 8
I/TestView: onDetachedFromWindow()
总结
从中我们可以看出:
View默认为可见的,不是默认值时先调用onVisibilityChanged(),但是此时该View的尺寸、位置等信息都不知道。
可见性改变后才是调用带有两个参数的构造函数,当然,如果该View不是在layout中定义的话,会调用一个参数的构造函数。
从XMl文件中inflate完成(onFinishInflate())。
将View加到window中(View是gone的,那么View创建生命周期也就结束)。
测量view的长宽(onMeasure())。
定位View 在父View中的位置(onLayout()),若View是invisible,则View的创建生命周期结束。
绘制View的content(onDraw()),只有可见的View才在window中绘制。
View的销毁流程和可见性没有关系。
综上所述:View的关键生命周期为:
[改变可见性] –> 构造View() –> onFinishInflate() –> onAttachedToWindow() –> onMeasure() –> onSizeChanged() –> onLayout() –> onDraw() –> onDetackedFromWindow()
自定义View时我们不可避免的要和View生命周期相关函数打交道,可能需要重新其中的某个或某几个来满足定制的需求,因此了解View的生命周期是Android程序猿进阶的必经之路。当然,我们没必要重新所有的方法,如果我们只是单纯的想把一个Bitmap画到View上,那我们只要重写View的onDraw方法就可以了,事实上自定义View的大部分情况我们也只是关注这个方法。
View/ViewGroup的生命周期相关推荐
- iOS7应用开发5、视图控制器View Controller及其生命周期
1.UITextView: 该类与Label类类似,可显示多行,可以编辑内容,可以滚动查看内容: 包含属性NSTextStorage *textStorage,该类是NSMutableAttribut ...
- SAP UI5 视图控制器 View Controller 的生命周期方法 - Lifecycle methods
SAPUI5 View Controller lifecycle methods Create an Application Project for SAPUI5 打开 Eclipse 并转到菜单选项 ...
- Android Fragment 生命周期及其正确使用(建议使用自定义View替换Fragment)
使用Fragment 官方例子中显示: 例如:一个学生Fragment,需要传入studentId,进行http请求显示,那么setArguments后防止杀掉Fragment后,参数为0,显示不了数 ...
- android自定义的生命周期,android 自定义控件之ViewGroup生命周期执行步骤(示例代码)...
前言 了解ViewGroup的生命周期的执行步骤对于自己自定义ViewGroup的时候十分重要,清楚了整个流程才能对ViewGroup有更深的理解.本文从个人的总结,来阐述一下执行的顺序. 执行说明 ...
- Android View生命周期
View的关键生命周期为: > 构造View() --> onFinishInflate() --> onAttachedToWindow() --> onMeasure() ...
- 关于FragmentManager动态管理Fragment时Fragment生命周期的探究
Fragment是Android中的重要组件,在Android 3.0的时候添加进来. 关于Fragment的生命周期,我相信了解过的开发人员都应该把以下方法脱口而出:onAttach, onCrea ...
- android自定义view生命周期,android基础之自定义view
一.Custom View 1.view的继承关系 view继承关系.png 2.Android 如何绘制试图层次 当activity获取焦点时,它必须提供layout层次的根节点,然后android ...
- iOS视图控制对象生命周期-init、viewDidLoad、viewWillAppear、viewDidAppear、viewWillDisappear、view...
iOS视图控制对象生命周期: init.viewDidLoad.viewWillAppear.viewDidAppear.viewWillDisappear.viewDidDisappear的区别及用 ...
- View的生命周期方法和Activity生命周期方法关系
View 是在Activity 中使用到的,所以在自定义View的时候,我们需要了解Activity 生命周期方法和View的生命周期方法调用先后顺序. 见如下图 (1) 在Activity onC ...
最新文章
- 内存、性能问题分析的利器——valgraind
- LeetCode实战:求众数
- 0分配不到地址_前端学习计算机网络——IP地址的划分及其分类
- Visual Studio“15”启动速度提升
- Codeforces Round #326 (Div. 2) B. Pasha and Phone C. Duff and Weight Lifting
- 美国佐治亚大学计算机专业,乔治亚大学计算机科学类排名,真是细致的看
- HDU 5898 odd-even number
- HDU3068 最长回文【manacher算法】
- Scrum Meeting---Ten(2015-11-5)
- DDOS 攻击工具
- 使用定位技术,边界判断要谨慎
- 项目01——图书进、销、存(jxc)系统(单机版)
- 产品使用报告(产品分析)
- 关于学习Godot时遇到的问题(未解决)
- 《浪潮之巅》内容整理
- IBM Spectrum LSF Suites
- Egret 利用ImageLoader加载服务器图片
- 如何使用格式工厂将vtt文件格式字幕加在视频文件中
- 基于微信点餐外卖小程序设计与实现 开题报告
- 生日快乐程序_时光匆匆,爱你不变——祝星广十七岁生日快乐