根据View的绘制机制,只有在程序完成绘制之后,才可以得到空间的高度,因此在OnCreate()中是得不到空间的高度了
解决
1:我们自己来测量
int w = View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
imageView.measure(w, h);
int height = imageView.getMeasuredHeight();
int width = imageView.getMeasuredWidth();
2:注册一个ViewTreeObserver的监听回调,这个监听回调,就是专门监听绘图的,既然是监听绘图,那么我们自然可以获取测量值了,同时,我们在每次监听前remove前一次的监听,避免重复监听。
ViewTreeObserver vto = imageView.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
vto.removeOnPreDrawListener(this);
int height = imageView.getMeasuredHeight();
int width = imageView.getMeasuredWidth();
return true;
}
});
3:全局的布局改变监听器(推荐使用)
ViewTreeObserver vto = imageView.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
imageView.getHeight();
imageView.getWidth();
}
});
这种方法于第2个方法基本同样,但他是全局的布局改变监听器,所以是最推荐使用的。
我看还有人说在Activity的OnPostCreate()中完成可以获取控件狂傲,在执行onPostCreate时,程序已经完全运行起来了,所以在onPostCreate中获取控件的高和宽,但是我测试显示,此时获取控件的宽高
//自己测量控件的高度
int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
tvName.measure(w,h);
int height = tvName.getMeasuredHeight();
int widt = tvName.getMeasuredWidth();
Log.d(TAG,"=============MeasureSpec Width"+widt+" height:"+widt);
//全局的布局改变监听器(推荐使用)
ViewTreeObserver vto = tvName.getViewTreeObserver();
vto.addOnGlobalFocusChangeListener(new ViewTreeObserver.OnGlobalFocusChangeListener() {
@Override
public void onGlobalFocusChanged(View oldFocus, View newFocus) {
Log.d(TAG,"=============ViewTreeObserver Width"+tvName.getWidth()+" height:"+tvName.getHeight());
}
});
ViewTreeObserver vto = tvName.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
Log.d(TAG,"=============addOnPreDrawListener Width"+tvName.getWidth()+" height:"+tvName.getHeight());
return true;
}
});
@Override
protected void onPostCreate(@Nullable Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
Log.d(TAG,"=============onPostCreate Width"+tvName.getWidth()+" height:"+tvName.getHeight());
}
11-20 23:25:43.006 7925-7925/com.course.myapplication D/MainActivity: =============MeasureSpec Width193 height:193
11-20 23:25:43.009 7925-7925/com.course.myapplication D/MainActivity: =============onPostCreate Width0 height:0
11-20 23:25:43.131 7925-7925/com.course.myapplication D/MainActivity: =============addOnGlobalFocusChangeListener Width60 height:216
11-20 23:25:43.131 7925-7925/com.course.myapplication D/MainActivity: =============addOnPreDrawListener Width60 height:216
从实际的效果来看:
第二,三种方法获取的宽高是正确的,
第一种方法获取的宽高不为0,但也不正确
而 onPostCreate获取的宽高为0,
如果有任何错误欢迎指正