天天看點

解決onCreate中不能擷取View寬高

在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();
            }
        });
    }
           

繼續閱讀