您好,登錄后才能下訂單哦!
《Android開(kāi)發(fā)藝術(shù)探索》筆記:
在Activity的onCreate()或者onResume()中去獲得View的高度的時(shí)候不能正確獲得寬度和高度信息,這是因?yàn)?View的measure過(guò)程和Activity的生命周期不是同步執(zhí)行的,因此無(wú)法保證Activity執(zhí)行了onCreate onStart onResume時(shí),某個(gè)View已經(jīng)測(cè)量完畢了,如果還沒(méi)有測(cè)量完,那么獲得的寬高就是0??梢酝ㄟ^(guò)下面幾種方式來(lái)獲得:
1、onWindowFocusChanged
onWindowFocusChanged:View已經(jīng)初始化完畢,寬高已經(jīng)有了,需要注意onWindowFocusChanged會(huì)被調(diào)用多次,Activity得到焦點(diǎn)和失去焦點(diǎn)都會(huì)執(zhí)行這個(gè)回調(diào),見(jiàn)下圖:
1、Activity首次進(jìn)入的時(shí)候執(zhí)行的方法
2、跳轉(zhuǎn)到另一個(gè)Activity時(shí)
3、返回到當(dāng)前Activity時(shí)
可見(jiàn)當(dāng)執(zhí)行onResume和onPause時(shí),onWindowFocusChanged都會(huì)被調(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)
通過(guò)post可以將一個(gè)runnable投遞到消息隊(duì)列的尾部,等待Looper調(diào)用此runnable的時(shí)候,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)可以完成這個(gè)功能,比如使用OnGlobalLayoutListener這個(gè)接口,當(dāng)View樹(shù)的狀態(tài)發(fā)生改變或者View樹(shù)內(nèi)部的View的可見(jiàn)性發(fā)生改變時(shí),OnGlobalLayout方法將會(huì)被回調(diào),這是獲取View寬高很好的一個(gè)時(shí)機(jī),需要注意的是,伴隨著View樹(shù)的狀態(tài)改變,OnGlobalLayout會(huì)被調(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)
通過(guò)手動(dòng)對(duì)View進(jìn)行measure來(lái)得到View的寬高,這里要分情況處理,根據(jù)View的LayoutParams來(lái)分:
match-parent
無(wú)法測(cè)出具體的寬高,因?yàn)楦鶕?jù)View的measure過(guò)程,構(gòu)造此種MeasureSpec需要知道parentSize,即父容器的剩余空間,而這個(gè)值我們是不知道的,所以不能測(cè)出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)制表示,也就是說(shuō)最大是30個(gè)1,也就是(1 << 30) - 1,在最大化模式下,我們用View理論上能支持的最大值去構(gòu)造MeasureSpec是合理的。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。