Android查缺補漏(View篇)--在 Activity 的 onCreate() 方法中為什麼擷取 View 的寬和高為0?

來源:互聯網
上載者:User

標籤:學習   this   解決方案   一起學   任務   height   boolean   utils   find   

在 Activity 的 onCreate() 方法中為什麼擷取 View 的寬和高為0 ?
@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_my_view);    myview = ViewUtils.find(this, R.id.myview);    getViewSize("onCreate");}private void getViewSize(String methodTag) {    int width = myview.getWidth();    int height = myview.getHeight();    Log.i(TAG, methodTag + ": width=" + width + " | height=" + height);}

log如下:

12-15 17:04:55.470 29286-29286/cn.codingblock.view I/MyViewActivity: onCreate: width=0 | height=0

如上面代碼結果所示,在Activity的onCreate()方法中我們嘗試擷取控制項的寬和高,卻擷取得是0,這是因為 View 繪製和 Activity 的生命週期方法並不同步,即使 Activity 回調了 onCreate()、onStart()、onResume() 方法,View 也不一定同步完成繪製,所以此時在這些方法裡面擷取 View 的尺寸時就擷取不到,解決方案有以下幾種:

方法一、在 Activity 的 onWindowFocusChanged() 方法中擷取 View 的尺寸。
在 Activity 中,當對所有的 View 初始化完畢後,會回調 onWindowFocusChanged() 方法。
/** * 方案一 * 當 View 初始化完畢是回調 * 當 Activity 每次擷取和失去焦點時回調 * @param hasFocus */@Overridepublic void onWindowFocusChanged(boolean hasFocus) {    super.onWindowFocusChanged(hasFocus);    getViewSize("onWindowFocusChanged");}
方法二、使用 View.post() 將任務post到訊息佇列中,當view初始化完畢後looper會執行任務。
@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_my_view);    myview = ViewUtils.find(this, R.id.myview);    // 方案二、將任務post到訊息佇列中,當view初始化完畢後looper會執行任務    myview.post(new Runnable() {        @Override        public void run() {            getViewSize("post");        }    });}
方法三、可以使用 ViewTreeObserver 的一些監聽介面。
例如:當 View 樹的狀態或者 View 樹內部的 View 的可見度發生改變時,ViewTreeObserver.OnGlobalLayoutListener 介面的 onGlobalLayout() 會被回調,可以在此方法內部擷取 View  的尺寸。
@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_my_view);    myview = ViewUtils.find(this, R.id.myview);    // 方案三、當 View 樹的狀態或者 View 樹內部的 View 的可見度發生改變時,    // ViewTreeObserver.OnGlobalLayoutListener 介面的 onGlobalLayout() 會被回調,    // 可以在此方法內部擷取 View  的尺寸    ViewTreeObserver observer = myview.getViewTreeObserver();    observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {        @Override        public void onGlobalLayout() {            getViewSize("onGlobalLayout");        }    });}

當然除了以上方法之外還會有其他的方法,例如可以使用延時或者在onCreate()方法中手動調用 View 的測量方法,相對而言以上幾種方法更為方便。

最後想說的是,本系列文章為博主對Android知識進行再次梳理,查缺補漏的學習過程,一方面是對自己遺忘的東西加以複習重新掌握,另一方面相信在重新學習的過程中定會有巨大的新收穫,如果你也有跟我同樣的想法,不妨關注我一起學習,互相探討,共同進步!

參考文獻:

  • 《Android開發藝術探索》
  • 《Android開發進階從小工到專家》

Android查缺補漏(View篇)--在 Activity 的 onCreate() 方法中為什麼擷取 View 的寬和高為0?

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.