Android中的onWindowFocusChanged()方法詳解

yangxi_001發表於2016-12-20

Android中獲取手機螢幕的高度和寬度,我們知道在onCreate方法中獲取到的值都是為0的,有人說可以在onClick方法中獲取值,這個也是個方法 ,但在onWindowFocusChanged方法中可以直接獲取到,而且有的時候場景的需要,就不得不在Activity渲染完成後立馬獲取值,這時候onWindowFocusChanged()方法就用到實處了,類似的有PopupWindow的顯示(顯示一個頁面的教育頁面的時候需要用到),如果在onCreate方法中執行的話,會報沒有token的一場,就是因為Activity沒有渲染成功.

onWindowFocusChanged():當Activity的當前Window獲得或失去焦點時會被回撥此方法。當回撥了這個方法時表示Activity是完全對使用者可見的(只是可見,還一片黑呼呼的,有待draw..)。當對話方塊彈起/消失及Activity新建立及回退等都會呼叫此方法。


相比之下,onResume()方法更多的是指Activity進入了可見的狀態,但只是狀態,並不是真正的介面構建完成了。

眼見為實,動手實踐。

寫了個簡單的demo,一個Activity只顯示一個TestImageView,並重寫TestImageView下的onMeasure()、onLayout()、onDraw()方法,並對其設定onGlobalLayout()監聽,觀察這幾個方法與Activity的onResume()、onWindowFocusChanged()的呼叫順序,如下:


[html] view plaincopy
  1. ClipDrawableActivity onCreate() time=1376920332125  
  2. ClipDrawableActivity onResume() TestImageView.width=0 time=1376920332149  
  3. MainActivity onWindowFocusChanged hasFocus=false  
  4. ClipDrawableActivity TestImageView onMeasure()  
  5. ClipDrawableActivity TestImageView onMeasure()  
  6. ClipDrawableActivity TestImageView onMeasure()  
  7. ClipDrawableActivity TestImageView onMeasure()  
  8. ClipDrawableActivity TestImageView onLayout()  
  9. ClipDrawableActivity onGlobalLayout() TestImageView.width=736 time=1376920332185  
  10. ClipDrawableActivity onWindowFocusChanged() hasFocus=true TestImageView.width=736 time=1376920332187  
  11. ClipDrawableActivity TestImageView onMeasure()  
  12. ClipDrawableActivity TestImageView onMeasure()  
  13. ClipDrawableActivity TestImageView onLayout()  
  14. ClipDrawableActivity onGlobalLayout() TestImageView.width=736 time=1376920332194  
  15. ClipDrawableActivity TestImageView onDraw()  

其呼叫順序為Activity.oncreate()→Activity.onResume()→
→TestImageView.onMeasure()→TestImageView.onLayout()→onGlobalLayoutListener()→
→Activity.onWidnowFocusChanged()→.....→
→TextImageView.onDraw()

至此,如果需要獲取某個View的寬高,可以在onWindowFocusChanged()處直接獲取即可,這比對某個view設定onGlobalLayoutListener的方式來獲取方便了許此。又比如,對於需要讀取本地檔案記錄來判斷是否是第一次開啟介面去提示文字圖片的,也可以在此方法中去讀取然後再顯示在ui上。

相關文章