Android 在onCreate()方法中获取控件宽高值为0解决方案
大家很多時候需要在Activity或者Fragment的onCreate()方法中獲取聲明的空間的高度或者寬度,進(jìn)行位置移動或者其他操作,但是當(dāng)調(diào)用 view.getHeight() 或者 view.getWidth() 獲取的竟然為0。。。
其實(shí)很容易理解,在onCreate()的時候,實(shí)際上控件只是聲明了,并沒有繪制完成,沒有attach到window上,所以導(dǎo)致獲取的高度和寬度為0,那么該怎么解決呢?
三種方式
1、使用下面的post方式
view.post(new Runnable() {@Overridepublic void run() {int height = view.getHeight() ;int width = view.getWidth();} });原理:
-
View.post(Runnable) 內(nèi)部會自動分兩種情況處理,當(dāng) View 還沒 attachedToWindow 時,會先將這些 Runnable 操作緩存下來;否則就直接通過 mAttachInfo.mHandler 將這些 Runnable 操作 post 到主線程的 MessageQueue 中等待執(zhí)行。
-
如果 View.post(Runnable) 的 Runnable 操作被緩存下來了,那么這些操作將會在 dispatchAttachedToWindow() 被回調(diào)時,通過 mAttachInfo.mHandler.post() 發(fā)送到主線程的 MessageQueue 中等待執(zhí)行。
想了解更多請去查看源碼。相信你可以更深層次的理解。
View.post() 中的操作執(zhí)行時,View 的寬高已經(jīng)計算完畢,所以可以在 Activity 的 onCreate() 里調(diào)用 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 注冊一個觀察者來監(jiān)聽視圖樹,當(dāng)視圖樹的布局、視圖樹的焦點(diǎn)、視圖樹將要繪制、視圖樹滾動等發(fā)生改變時,ViewTreeObserver都會收到通知。所以 這個方法會調(diào)用很多次,如果要使用這種方法的話,要做好規(guī)避調(diào)用多次,記得移除監(jiān)聽;ViewTreeObserver不能被實(shí)例化,可以調(diào)用View.getViewTreeObserver()來獲得。
3、還有一種不太推薦
@Override public void onWindowFocusChanged(boolean hasFocus) {super.onWindowFocusChanged(hasFocus);int height = view.getHeight()int width = view.getHeight(); }這個函數(shù)的含義是:view已經(jīng)初始化完畢了,寬/高已經(jīng)準(zhǔn)備好了,這個時候去獲取寬高是可以成功獲取的。需要注意的是 onWindowFocusChanged函數(shù)會被調(diào)用多次,當(dāng)Activity的窗口得到焦點(diǎn)和失去焦點(diǎn)時均會被調(diào)用一次,如果頻繁地進(jìn)行onResume和onPause,那么onWindowFocusChanged也會被頻繁地調(diào)用,不太適合處理一些復(fù)雜的業(yè)務(wù)邏輯。
總結(jié)
以上是生活随笔為你收集整理的Android 在onCreate()方法中获取控件宽高值为0解决方案的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WGAN (原理解析)
- 下一篇: Android Studio Gradl