天天看點

擷取android activity view,Android的Activity擷取View寬高的常用方式

假如我們在Activity已經啟動完之後,需要擷取一個View的寬/高。可能大部分人都試過在onCreate、onStart、onResume中擷取寬/高,然而擷取的結果均為 0。這是因為View的measure過程和Activity的生命周期并不是同步執行的,是以無法保證在onCreate、onStart、onResume中擷取寬/高時View已經測量完了,如果沒有測量完,獲得的寬/高就是0。

我們用以下幾個方法解決這個問題:

一、Activity/View#onWindowFocusChanged

onWindowFocusChanged的含義:View已經初始化完畢了,寬/高已經準備好了,這個時候擷取寬/高是沒有問題的。當Activity的目前Window獲得或失去焦點時會回調此方法,也就是說當Activity暫停執行和繼續執行都會回調此方法,即這個方法會被頻繁調用。我們一般在第一次擷取焦點時擷取寬高,代碼如下:

private boolean isFirstFocus = true;

@Override

public void onWindowFocusChanged(boolean hasFocus) {

super.onWindowFocusChanged(hasFocus);

if (hasFocus&&isFirstFocus){

isFirstFocus = false;

int width = view.getMeasuredWidth();

int height = view.getMeasuredHeight();

}

}

二、view.post(runnable)

利用 Handler 通信機制,通過post将添加一個 Runnable到message queue的隊尾,當View初始化完成之後,Looper會調用此runnable,然後通知UI線程。代碼如下:

@Override

protected void onStart() {

super.onStart();

view.post(new Runnable() {

@Override

public void run() {

int width = view.getMeasuredWidth();

int height = view.getMeasuredHeight();

}

});

}

三、ViewTreeObserver

當View樹狀态發生改變,或者View樹内部的view的可見性發生改變時,onGlobalLayout會被回調,是以這也是擷取寬高的一個很好的時機。伴随着View樹的狀态的改變,onGlobalLayout會被調用多次,是以可在第一次調用完後,移除監聽事件。代碼如下:

@Override

protected void onStart() {

Logger.e("onStart");

super.onStart();

ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();

viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

@Override

public void onGlobalLayout() {

view.removeOnLayoutChangeListener(this);

int width = view.getMeasuredWidth();

int height = view.getMeasuredHeight();

}

});

}

四、View#addOnLayoutChangeListener

監聽 View的onLayout()的繪制過程,一旦寬/高發生變化就會回調onLayoutChange方法。是以可在第一次調用完後,移除監聽事件。代碼如下:

view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {

@Override

public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {

view.removeOnLayoutChangeListener(this);

Logger.e("w/h:" + view.getWidth() + "-" + view.getHeight());

}

});