1. 程式人生 > >android 開發 在oncreate()中獲取到控制元件的高度和寬度值為0解決辦法

android 開發 在oncreate()中獲取到控制元件的高度和寬度值為0解決辦法

大家很多時候需要在activity或者fragment的oncreate()方法中獲取宣告的空間的高度或者寬度,進行位置移動或者其他操作,但是當呼叫view.getHeight()或者view.getWidth()獲取的竟然為0。。。黑人問號。。。
其實很容易理解,在oncreate的時候,實際上控制元件只是聲明瞭,並沒有繪製完成,沒有attach到window上,所以導致獲取的高度和寬度為0,那麼該怎麼解決呢?

兩種方法
1、使用下面的post方式:

view.post(new Runnable() {
     @Override
     public void run() {
         int
height= view.getHeight() ; } });

同理寬度改為下面的即可。

view.post(new Runnable() {
     @Override
     public void run() {
         int height= view.getWidth() ;
      }
});

原理:(1)View.post(Runnable) 內部會自動分兩種情況處理,當 View 還沒 attachedToWindow 時,會先將這些 Runnable 操作快取下來;否則就直接通過 mAttachInfo.mHandler 將這些 Runnable 操作 post 到主執行緒的 MessageQueue 中等待執行。
(2)如果 View.post(Runnable) 的 Runnable 操作被快取下來了,那麼這些操作將會在 dispatchAttachedToWindow() 被回撥時,通過 mAttachInfo.mHandler.post() 傳送到主執行緒的 MessageQueue 中等待執行。

想了解更多請去檢視原始碼。相信你可以更深層次的理解。

View.post() 中的操作執行時,View 的寬高已經計算完畢,所以可以在 Activity 的 onCreate() 裡呼叫 View.post() 來解決獲取 View 寬高為0的問題。

2、使用ViewTreeObserver 的方式:

ViewTreeObserver vto = view.getRabbit().getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
    public boolean
onPreDraw() { if(vto.isAlive()){ vto.removeOnDrawListener(this); } int height = view.getMeasuredHeight()); return true; } });

ViewTreeObserver 註冊一個觀察者來監聽檢視樹,當檢視樹的佈局、檢視樹的焦點、檢視樹將要繪製、檢視樹滾動等發生改變時,ViewTreeObserver都會收到通知。所以這個方法會呼叫很多次,如果要使用這種方法的話,要做好規避呼叫多次,記得移除監聽;ViewTreeObserver不能被例項化,可以呼叫View.getViewTreeObserver()來獲得。
3、還有一種不太推薦:

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    int height = view.getHeight()
    int width = view.getHeight();
}

這個函式的含義是:view已經初始化完畢了,寬/高已經準備好了,這個時候去獲取寬高是可以成功獲取的。需要注意的是onWindowFocusChanged函式會被呼叫多次,當Activity的視窗得到焦點和失去焦點時均會被呼叫一次,如果頻繁地進行onResume和onPause,那麼onWindowFocusChanged也會被頻繁地呼叫,不太適合處理一些複雜的業務邏輯。

好了,小夥伴,加油!