因为View的measure过程和Activity的生命周期是不同步的,无法保证Activty执行了onCreate、onStart、onResume时某个View已经测量完毕了,如果View还没测量完成,那么获取的宽和高为0,所以我们不能在onCreate和onStart中直接获取宽和高。这里有四种解决方案。
1:Activity/View#onWindowFocusChanged
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(hasFocus){
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
}
}
2:view.post(runnable)
@Override
protected void onStart() {
super.onStart();
view.post(new Runnable() {
@Override
public void run() {
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
}
});
}
3:ViewTreeObserver
@Override
protected void onStart() {
super.onStart();
ViewTreeObserver observer = view.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
}
});
}
4:view.measure(int widthMeasureSpec,int heightMeasureSpec)
通过手动对View进行measure来得到View的宽和高。根据View的LayoutParams来分
match_parent
这种情况下无法获取View的宽和高,构造此种MeasureSpec需要知道parentSize,即父容器的剩余空间,而这个时候我们无法知道parentSize的大小,理论上不可能测量出View的大小。
具体数值(dx/px)
比如宽和高都是100px,如下measure:
int widthMeasureSpc = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY);
int heightMeasureSpc = View.MeasureSpec.makeMeasureSpec(100,View.MeasureSpec.EXACTLY);
view.measure(widthMeasureSpc,heightMeasureSpc);
wrap_content
int widthMeasureSpc = View.MeasureSpec.makeMeasureSpec((1 << 30) -1, View.MeasureSpec.AT_MOST);
int heightMeasureSpc = View.MeasureSpec.makeMeasureSpec((1 << 30) -1,View.MeasureSpec.AT_MOST);
view.measure(widthMeasureSpc,heightMeasureSpc);