在Android开发过程中,有可能遇到在Activity的onCreate方法中获取控件宽高的需求,这时利用view.getWidth()或view.getMeasuredWidth()等方法获取控件的宽高,得到的值总是0。是因为当OnCreate函数发生时,只是提供了数据初始化的机会,此时还没有正式绘制界面。而绘制界面是在OnDraw方法中进行的,此时计算又显得太晚。这时可以利用Android提供的监听机制来获取控件的宽高,下面给出几种在Activity的onCreate中获取控件宽高的方法:
1、利用ViewTreeObserver添加OnPreDrawListener监听,该监听在绘制控件前的一刹那进行回调,示例如下:
ViewTreeObserver vto = mView.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
if (hasMeasured == false) {// 只执行一次就够了
Toast.makeText(MainActivity.this, "mView:width=" + mView.getWidth() + ";height=" + mView.getHe ight(), Toast.LENGTH_SHORT).show();
hasMeasured = true;
}
return true;
}
});
注:此回调监听会在控件绘制时调用多次,在控件滑动的时候仍然会再次调用,所以定义了一个boolean类型的变量hasMeasured,保证方法体只执行一次。
2、利用ViewTreeObserver添加OnGlobalLayoutListener,OnGlobalLayoutListener 是
ViewTreeObserver vto2 = mView.getViewTreeObserver();
vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
tv_show.getViewTreeObserver().removeGlobalOnLayoutListener(this);//移除注册,让代码只执行一次
Toast.makeText(MainActivity.this, "mView:width=" + mView.getWidth() + ";height=" + mView.getHeight(), Toast.LENGTH_SHORT).show();
}
});
3、利用view.post()方法
mView.post(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "mView:width=" + mView.getWidth() + ";height=" + mView.getHeight(), Toast.LENG TH_SHORT).show();
}
});
另,网上有些人说利用measure()方法也可在onCreate方法中获取控件的宽高,代码如下:
int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
mView.measure(w, h);
int height = tv_show.getMeasuredHeight();
int width = tv_show.getMeasuredWidth();
Toast.makeText(MainActivity.this, "mView:width=" + width + ";height=" + height, Toast.LENGTH_SHORT).show();
但是经本人亲测,获取的控件的宽高确实不为0,但是跟控件实际设置的值是不一样的。故,此方法不可取。