在onCreate或者onResume中不能擷取view 的寬高是因為:view的measure過程和activity的生命周期不是同步執行的,是以無法保證執行onCreate,onStart,onResume時某個view已經測量完畢,這裡給出三個解決方案:
注意:本人簡單測試了Fragment中利用view.post(runnable);不能達到效果,感興趣的可以再試試。
(1)onWindowFocusChanged
onWindowFocusChanged是:view已經初始化完畢,寬高已經準備好,需要注意的是:onWindowFocusChanged會被多次調用,視窗得到焦點(onResume)和失去焦點(onPause)時調用:
@Override
public void onWindowFocusChanged(boolean hasFocus) {
// TODO Auto-generated method stub
super.onWindowFocusChanged(hasFocus);
if(hasFocus){
width=view.getMeasuredWidth();
}
}
(2)view.post(runnable)
通過post可以将runnable投遞到消息隊列尾部,然後等待Looper調用此runnable的時候,view已經初始化好:
@Override
protected void onStart() {
super.onStart();
btn.post(new Runnable() {
@Override
public void run() {
width=view.getMeasuredWidth();
}
});
}
(3)ViewTreeObserver
ViewTreeObserver含義是:當view樹狀态發生改變或者view樹内部的view可見性發生改變時,onGlobalLayout方法将會被回調,該方法會被調用多次:
@Override
protected void onStart() {
super.onStart();
ViewTreeObserver observer=view.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@SuppressLint("NewApi")
@Override
public void onGlobalLayout() {
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
width=view.getMeasuredWidth();
}
});
}