Android里面我们经常会使用view.getWidth()/view.getHeight,但是我们又经常会发现得到的结果为0,那么view的宽、高到底是什么时候开始有值的呢?
今天我做了一个简单的实验,简单的继承了一个View,然后重写了里面的一些初始化方法。
public class MyView extends View{
private static final String TAG = "MyView";
public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
Log.i(TAG, "MyView,width:"+getWidth()+",height:"+getHeight());
}
public MyView(Context context) {
super(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
Log.i(TAG, "onMeasure,width:"+getWidth()+",height:"+getHeight()+",widthMeasureSpec:"+widthMeasureSpec+",heightMeasureSpec:"+heightMeasureSpec);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
Log.i(TAG, "onAttachedToWindow,width:"+getWidth()+",height:"+getHeight());
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
Log.i(TAG, "onDetachedFromWindow,width:"+getWidth()+",height:"+getHeight());
}
@Override
protected void onWindowVisibilityChanged(int visibility) {
super.onWindowVisibilityChanged(visibility);
Log.i(TAG, "onDetachedFromWindow,width:"+getWidth()+",height:"+getHeight());
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
Log.i(TAG, "onSizeChanged,width:"+getWidth()+",height:"+getHeight());
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
Log.i(TAG, "onFinishInflate,width:"+getWidth()+",height:"+getHeight());
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.i(TAG, "onDraw,width:"+getWidth()+",height:"+getHeight());
}
}
运行结果:
看着上面的日志,我们会发现width/height第一次不为0的时候是在:onSizeChanged里面,并且经过了两次测量,所以有些博客上会说在第三次执行测量的时候宽度、高度就会确定。所以这时,我们就可以使用控件的宽、高了。
现在我们在退出程序:
这时我们就可以看到,view执行的一套简单的流程(即view的生命周期)。
看着上面的日志,仔细的朋友可能会发现,怎么进入程序的时候会执行onDetachedFromWindow?其实看着它,我也是醉了,这个不是应该view销毁的时候执行吗?再看看程序退出的时候,onDetachedFromWindow居然执行了两遍,更是醉了,然后我果断打断点调试,发现刚进入程序的时候并没有进入onDetachedFromWindow,而退出程序的时候onDetachedFromWindow也只执行了一次。我还是有点纳闷,队员了的程序稍稍修改了一下:
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
Log.i(TAG, "onDetachedFromWindow,width:"+getWidth()+",height:"+getHeight());
Log.i(TAG, "onDetachedFromWindow,width:"+getWidth()+",height:"+getHeight());
}
我们在执行并退出程序:
会发现程序进入的时候onDetachedFromWindow还是只执行了一次,而退出的时候,只有一次好像是完成执行了。
然后我在对代码做出了稍稍改动:
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
Log.i(TAG, "onDetachedFromWindow,width:"+getWidth()+",height:"+getHeight());
Log.i(TAG, "onDetachedFromWindow,width:"+getWidth()+",height:"+getHeight());
Log.i(TAG, "onDetachedFromWindow,width:"+getWidth()+",height:"+getHeight());
}
执行程序后,挥发向执行的结论,跟上面的一样。所以我就大胆假设,进入程序的时候onDetachedFromWindow应该是虚拟执行了(姑且称为),而程序退出的时候,也应该是虚拟执行了第二次。(如果有知道详情的朋友可以分享一下)
onDetachedFromWindow