Android view 的宽高到底什么时候确定与view生命周期

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值