前言
- 在activity中携茂,經(jīng)常需要獲取view的width和height,但是在onCreate()獲取view的width和height會得到0窃爷。view.getWidth()和view.getHeight()為0的根本原因是:控件還沒有完成繪制邑蒋。這種情況當我們使用動態(tài)布局(使用wrap_content或match_parent)就會出現(xiàn)。
- 一般來講在Activity.onCreate(...)按厘、onResume()方法中都沒有辦法獲取到View的實際寬高医吊。So,我們必須用一種變通的方法,等到View繪制完成后去獲取width和Height逮京。
- 下面有一些可行的解決方案:
1. 監(jiān)聽Draw/Layout事件:ViewTreeObserver
ViewTreeObserver監(jiān)聽很多不同的界面繪制事件卿堂。一般來說OnGlobalLayoutListener就是可以讓我們獲得到view的width和height的地方.下面onGlobalLayout內(nèi)的代碼會在View完成Layout過程后調(diào)用。
view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mScrollView.post(new Runnable() {
public void run() {
view.getHeight(); //height可用了
}
});
}
});
但是要注意這個方法在每次有些view的Layout發(fā)生變化的時候被調(diào)用(比如某個View被設(shè)置為Invisible),所以在得到你想要的寬高后懒棉,記得移除onGlobleLayoutListener:
在 SDK Lvl < 16時使用
public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim)
在 SDK Lvl >= 16時使用
public void removeOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim)
2. 將一個runnable添加到Layout隊列中:View.post()
這個解決方案是比較好的草描。簡單地說,只要用View.post()一個runnable就可以了策严。runnable對象中的方法會在View的measure穗慕、layout等事件后觸發(fā),UI事件隊列會按順序處理事件妻导。在setContentView()被調(diào)用后逛绵,事件隊列中會包含一個要求重新layout的message,所以任何post到隊列中的東西都會在Layout發(fā)生變化后執(zhí)行倔韭。
view.post(new Runnable() {
@Override
public void run() {
view.getHeight(); //height可用
}
});
3. 重寫View的onLayout方法
這個方法謹慎使用术浪,一般用在:所要執(zhí)行的代碼應(yīng)該作為內(nèi)部邏輯,從而實現(xiàn)高內(nèi)聚的view模塊寿酌,否者這個解決方案就顯得很耦合胰苏、拖拉。
view = new View(this) {
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
view.getHeight(); //height可用
}
};
需要注意的是onLayout方法會被調(diào)用很多次醇疼,所以要考慮好在這個方法中要做什么硕并,或者在第一次執(zhí)行后禁用掉代碼法焰。
4. 重寫Activity的onWindowFocusChanged方法
如果要獲取的view的width和height是固定的,那么可以直接使用:
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
//此處可以正常獲取width倔毙、height等
}
在Activity得到或者失去焦點的時候壶栋,就會被調(diào)用。Activity初始化完畢準備顯示的時候就會回調(diào)該方法普监。所以說,只要想做一些Activity加載完畢就馬上觸發(fā)的事情琉兜,都可以在這里執(zhí)行凯正。
5. 獲取固定寬高
如果要獲取的view的width和height是固定的,那么可以直接使用:
View.getMeasureWidth()
View.getMeasureHeight()