問題描述
當(dāng)我們在onCreate()回調(diào)方法中去調(diào)用getLeft(), getRight(), getTop(), getBottom()枝恋、getLocationInWindow等值為0
問題原因
View的顯示必須經(jīng)歷Measure(測量)、Layout(布局)和Draw(繪制)過程格嗅。而在Measure與Layout過程完成之后底桂,View的width泉懦、height片部、top涤姊、left等屬性才被正確賦值,此時我們才能獲取到正確的值嗤放,這幾個過程都晚于onCreate執(zhí)行
解決方式
1思喊、 view post 一個runnable。
因為UI線程消息隊列會按順序處理事件次酌,在setContentView()被調(diào)用后恨课,消息隊列中會包含一個要求重新Layout的msg,所以任何你post到UI線程隊列中的東西都會在Layout后執(zhí)行岳服。
view.post(new Runnable() {
@Override
public void run() {
view.getHeight();
}
});
2剂公、重寫Activity的onWindowFocusChanged方法。
在Activity得到或者失去焦點的時候吊宋,就會被調(diào)用纲辽。Activity初始化完畢準(zhǔn)備顯示的時候就會回調(diào)該方法。所以說璃搜,只要想做一些Activity加載完畢就馬上觸發(fā)的事情拖吼,都可以在這里執(zhí)行。
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
//此處可以正常獲取width这吻、height等
}
3吊档、為View注冊監(jiān)聽器OnGlobalLayoutListener。
視圖樹的可視性或全局布局狀態(tài)發(fā)生變化時執(zhí)行的回調(diào)函數(shù)唾糯,此時已經(jīng)完成Layout過程怠硼,可能會被多次調(diào)用鬼贱,所以獲取完后就可以移除監(jiān)聽器
mView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//此處可以正常獲取width、height等
mView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});