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() ;
         int width = view.getWidth();
      }
});

原理:

  • View.post(Runnable) 內部會自動分兩種情況處理,當 View 還沒 attachedToWindow 時,會先將這些 Runnable 操作緩存下來;否則就直接通過 mAttachInfo.mHandler 將這些 Runnable 操作 post 到主線程的 MessageQueue 中等待執行。

  • 如果 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也會被頻繁地調用,不太適合處理一些複雜的業務邏輯

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章