Android 獲得View寬高的幾種方式總結(jié)
《Android開發(fā)藝術(shù)探索》筆記:
在Activity的onCreate()或者onResume()中去獲得View的高度的時候不能正確獲得寬度和高度信息,這是因?yàn)?View的measure過程和Activity的生命周期不是同步執(zhí)行的,因此無法保證Activity執(zhí)行了onCreate onStart onResume時,某個View已經(jīng)測量完畢了,如果還沒有測量完,那么獲得的寬高就是0??梢酝ㄟ^下面幾種方式來獲得:
1、onWindowFocusChanged
onWindowFocusChanged:View已經(jīng)初始化完畢,寬高已經(jīng)有了,需要注意onWindowFocusChanged會被調(diào)用多次,Activity得到焦點(diǎn)和失去焦點(diǎn)都會執(zhí)行這個回調(diào),見下圖:

1、Activity首次進(jìn)入的時候執(zhí)行的方法
2、跳轉(zhuǎn)到另一個Activity時
3、返回到當(dāng)前Activity時
可見當(dāng)執(zhí)行onResume和onPause時,onWindowFocusChanged都會被調(diào)用。
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
//獲得寬度
int width = view.getMeasuredWidth();
//獲得高度
int height = view.getMeasuredHeight();
}
}
2、view.post(runnable)
通過post可以將一個runnable投遞到消息隊(duì)列的尾部,等待Looper調(diào)用此runnable的時候,View也已經(jīng)初始化好了,示例:
@Override
protected void onStart() {
super.onStart();
view.post(new Runnable() {
@Override
public void run() {
int width=view.getMeasuredWidth();
int height=view.getMeasuredHeight();
}
})
}
3、ViewTreeObserver
使用ViewTreeObserver的眾多回調(diào)可以完成這個功能,比如使用OnGlobalLayoutListener這個接口,當(dāng)View樹的狀態(tài)發(fā)生改變或者View樹內(nèi)部的View的可見性發(fā)生改變時,OnGlobalLayout方法將會被回調(diào),這是獲取View寬高很好的一個時機(jī),需要注意的是,伴隨著View樹的狀態(tài)改變,OnGlobalLayout會被調(diào)用多次,示例:
@Override
protected void onStart() {
super.onStart();
ViewTreeObserver observer=view.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
int width=view.getMeasuredWidth();
int height=view.getMeasuredHeight();
}
});
}
4、view.measure(int widthMeasureSpec, int heightMeasureSpec)
通過手動對View進(jìn)行measure來得到View的寬高,這里要分情況處理,根據(jù)View的LayoutParams來分:
match-parent
無法測出具體的寬高,因?yàn)楦鶕?jù)View的measure過程,構(gòu)造此種MeasureSpec需要知道parentSize,即父容器的剩余空間,而這個值我們是不知道的,所以不能測出View的大小。
具體的數(shù)值(dp/px)
比如寬高都是100px,如下measure:
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY); int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY); view.measure(widthMeasureSpec, heightMeasureSpec);
wrap_content
如下measure:
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec((1 << 30) - 1, View.MeasureSpec.AT_MOST); int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec((1 << 30) - 1, View.MeasureSpec.AT_MOST); view.measure(widthMeasureSpec, heightMeasureSpec);
View的specSize使用30位二進(jìn)制表示,也就是說最大是30個1,也就是(1 << 30) - 1,在最大化模式下,我們用View理論上能支持的最大值去構(gòu)造MeasureSpec是合理的。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
分別用ToolBar和自定義導(dǎo)航欄實(shí)現(xiàn)沉浸式狀態(tài)欄
本文主要介紹了分別用ToolBar和自定義導(dǎo)航欄實(shí)現(xiàn)沉浸式狀態(tài)欄的方法步驟,具有一定的參考價值,下面跟著小編一起來看下吧2017-01-01
動態(tài)添加LinearLayout的高度實(shí)例
下面小編就為大家?guī)硪黄獎討B(tài)添加LinearLayout的高度實(shí)例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-04-04
android實(shí)現(xiàn)手機(jī)App實(shí)現(xiàn)拍照功能示例
本篇文章主要介紹了android實(shí)現(xiàn)手機(jī)App實(shí)現(xiàn)拍照功能示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02
Android實(shí)現(xiàn)九宮格(GridView中各項(xiàng)平分空間)的方法
這篇文章主要介紹了Android實(shí)現(xiàn)九宮格(GridView中各項(xiàng)平分空間)的方法,涉及Android針對GridView操作的相關(guān)技巧,需要的朋友可以參考下2015-06-06
Android隨機(jī)給出加減乘除的四則運(yùn)算算術(shù)題
這篇文章主要為大家詳細(xì)介紹了Android隨機(jī)給出加減乘除的四則運(yùn)算算術(shù)題,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-04-04
Android實(shí)現(xiàn)的RecyclerView適配器
這篇文章主要介紹了Android實(shí)現(xiàn)的RecyclerView適配器的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下2021-03-03
簡單掌握Android Widget桌面小部件的創(chuàng)建步驟
這篇文章主要介紹了簡單掌握Android Widget桌面小部件的創(chuàng)建步驟,Widget一般采用web前端技術(shù)進(jìn)行開發(fā),需要的朋友可以參考下2016-03-03

