View的生命周期

2016年3月30日 偶尔的坚持比科学更重要

最近常常用到自定义的View和ViewGroup,且发现在自定义时总是出现一些莫名奇妙的问题,其大部分的原因可以归咎于View的生命周期。

View相当于一个Panel,所有的UI组件都继承了View。为了了解他,让我们先看看他的一些方法。

View常被重写的方法

void onFinishInflate():当应用程序通过XML布局文件加载该组件从而进行构建界面时,该方法将会被调用

onMeasure(int widthMeasureSpec, int heightMeasureSpec):用来检测View组件和其子组件的大小,其参数为为该View设置的长和宽

onLayout(boolean changed, int left, int top, int right, int bottom) :用于分配view在父控件的位置,即给view布局

onSizeChanged(int w, int h, int oldw, int oldh):当该组件的大小被改变时,调用该方法

onDraw(Canvas canvas):用于绘制组件

onKeyDown(int keyCode, KeyEvent event):当有按键被按下时出发该方法(可以监听返回键,home键)

onKeyUp(int keyCode, KeyEvent event):当有按键被松开时出发该方法

onTouchEvent(MotionEvent event):当发生触摸屏事件时触发该方法

onAttachedToWindow():当将这个组件放入某个窗口时调用该方法

onDetachedFromWindow():当将这个组件从某个窗口分离时调用这个方法

onWindowVisibilityChanged(int visibility):当包含该组件的窗口的可见性发生改变时调用该方法

onVisibilityChanged(View changedView, int visibility):当该view的是否可见发生变化时,调用该方法

onWindowVisibilityChanged和onVisibilityChanged中visibility参数的三个值: visible 0 代表view可见,是默认值 invisible 4 代表组件不可见,但保留控件的布局位置 gone 8 代表组件隐藏,不保留控件的布局位置,如果组建的visibility属性为gone,则代表该组件生命周期结束

测试View的生命周期

简单的介绍了这些方法之后,让我们再来看这些这些方法什么时候会被调用。

下面是我的测试代码,还是有必要贴出来的:

xml文件: 为了方便测试我使用了绝对布局:

通过自定义View并输出的Log信息: 刚刚创建应用程序输出的Log:

从上面的Log信息可以看出,当应用第一次被打开时,首先会调用其构造方法,因为这个View是在XML中创建的,所以会调用MyView(context,attrs)这个构造器。 第二个参数代表XML传入的属性,比如:

attrs.getAttributeName(0)+ "===" + attrs.getAttributeName(2)

所获取的值为 id===layout_height 正好对应XML文件中设置的属性名称

然后调用了onFinishInflate方法,代表从XML文件加载该View完成 接着调用了onVisibilityChanged方法两次,第一次将View的visibility的属性设置为4 即不可见,第二次设置为0 即可见,这里不是很懂,为什么要调用两次。 接着调用了onAttachedToWindow,将其附加到窗口上。 onWindowVisibilityChanged0,窗口的Visibility属性为可见,这是我们可以看到窗口显示出来了。 调用了onMeasure方法,测量组件的大小,发现大小发生了变化,就调用了onSizeChanged方法,可以看见,View最初的w和h是0和0。 onMeasure方法结束后,就要为view设置他的布局了,所以这里调用了onLayout方法进行布局。 最后布局完成后,又再次调用onMeasure方法对组件的大小测量,因为在其他方法中view的组件的大小有可能再次发生变化。所以再次调用onMeasure和onLayout方法。 最后调用onDraw方法进行view的绘制。

当我点击home键时,View隐藏在了后台,其Log为:

然后我再次返回到View中

当我点击返回键时

view被从window中分离了出来,代表他的生命周期已经结束。

本文如有错,烦请指出,谢谢,欢迎交流。

最后更新于

这有帮助吗?