Android View如何測(cè)量
對(duì)于Android View的測(cè)量,我們一句話總結(jié)為:"給我位置和大小,我就知道您長到那里"。
為了讓大家更好的理解這個(gè)結(jié)論,我這里先講一個(gè)日常生活中的小故事:不知道大家玩過"瞎子畫畫"的游戲沒,一個(gè)人蒙上眼睛,拿筆去畫板上畫一些指定的圖案,另外一個(gè)人則充當(dāng)他的"眼睛",通過語言告訴他在畫板那個(gè)位置畫一個(gè)多大的圖案。倘若,這個(gè)人不告訴那個(gè)蒙著眼睛的人,在那個(gè)畫一個(gè)多大的圖案。那么這個(gè)蒙著眼睛的人此時(shí)真是"河里趕大車----------沒轍"。其實(shí),Android就是這個(gè)蒙著眼睛的人,我們必須精確地告訴他如何去畫,它才能畫出你所想要的圖形。
大家是不是對(duì)Android布局的測(cè)量進(jìn)行現(xiàn)實(shí)世界進(jìn)行類比了。為了實(shí)現(xiàn)View具體布局在哪兒,Android設(shè)計(jì)了一個(gè)短小精悍又功能強(qiáng)大的類——measureSpec類。這樣?jì)寢屧僖膊挥脫?dān)心我不會(huì)測(cè)量View了。那么,MeasureSpec到底是個(gè)什么鬼了。MeasureSpec,歸根結(jié)底是一個(gè)32位的int值。其中高2位表示測(cè)量的模式,低30位表示測(cè)量View的大小。這樣做有什么好處。這樣做通過位運(yùn)算來提高運(yùn)行效率。
要了解MeasureSpec這個(gè)類的來弄去脈的話,務(wù)必要對(duì)測(cè)量的三種模式了解。
1.EXACTLY(精準(zhǔn)的)
當(dāng)您設(shè)置View的layout_height屬性或layout_width屬性為確定的值或者為match_parent(填充父容器)時(shí)候,系統(tǒng)就將View測(cè)量模式設(shè)置為EXACTLY模式。
2.AT_MOST(最大值)
即布局為最大值模式,那么什么時(shí)候系統(tǒng)會(huì)將View調(diào)整為AT_MOST模式了,即當(dāng)您設(shè)置View的layout_height屬性或layout_width屬性為wrap_content(包裹內(nèi)容)時(shí)候。
3.UNSPECIFIED(未確定)
即沒有確定,沒有指定大小測(cè)量模式,view即“心有多大,舞臺(tái)就有多大"。這個(gè)方法,一般在自定義控件中才能用到。
View測(cè)量的時(shí)候,默認(rèn)是EXACTLY模式,也許你會(huì)感到納悶,TextView,EditText這些控件,他怎么就支持wrap_content屬性了,難道他重寫OnMeasure方法,是的,他們都重寫OnMeasure方法。這就是為什么我們?cè)谧远x控件的時(shí)候,如果要布局支持wrap_content屬性,就需要重寫onMeasure方法,來指定wrap_content為確切的大小。
這個(gè)關(guān)于測(cè)量模式的思維導(dǎo)圖應(yīng)該是這樣的:
我們知道這么多理論的知識(shí),是不是覺得即枯燥乏味又覺得然并卵。好吧,我們就直接上代碼,在代碼中解釋MeasureSpec如何獲取測(cè)量模式和測(cè)量的大小。源代碼如下:
Java代碼如下:
public class MyView extends View { public MyView(Context context, AttributeSet attrs) { super(context, attrs); } }
xml代碼如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <com.example.test.MyView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#00ff00" /> </LinearLayout>
運(yùn)行效果如下所示:
通過這個(gè)短小精悍的例子,充分證明這樣一個(gè)結(jié)論:View測(cè)量的時(shí)候,默認(rèn)是EXACTLY模式,你不重寫OnMeasure方法,即使設(shè)置wrap_content屬性,他也是填充父容器。
那么,就通過MeasureSpec這個(gè)萬金油類來重寫一下OnMeasure方法。相應(yīng)源代碼如下:
public MyView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(measureWidth(widthMeasureSpec), measureWidth(heightMeasureSpec)); } public int measureWidth(int measureSpec) { int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if (specMode == MeasureSpec.EXACTLY) { result = specSize; } else { result = 200; if (specMode == MeasureSpec.AT_MOST) { result = Math.min(specSize, result); } } return result; }
運(yùn)行效果如下:
同樣的例子,我們只不過是重寫了OnMeasure方法,通過MeasureSpec.getMode(measureSpec)獲取測(cè)量模式的時(shí)候,通過MeasureSpec.getSize(measureSpec)獲取控件尺寸。判斷當(dāng)布局屬性為wrap_content,指定為一確切值,這時(shí),控件就符合wrap_content屬性。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。
相關(guān)文章
完美解決EditText和ScrollView的滾動(dòng)沖突(上)
這篇文章主要為大家詳細(xì)介紹了完美解決EditText和ScrollView滾動(dòng)沖突的方法,感興趣的小伙伴們可以參考一下2016-06-06Android編程中selector背景選擇器用法實(shí)例分析
這篇文章主要介紹了Android編程中selector背景選擇器用法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Selector的結(jié)構(gòu)描述與使用技巧,需要的朋友可以參考下2016-01-01Android淺析viewBinding和DataBinding
這篇文章主要介紹了Android淺析viewBinding和DataBinding,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09android異步請(qǐng)求服務(wù)器數(shù)據(jù)示例
這篇文章主要介紹了android異步請(qǐng)求服務(wù)器數(shù)據(jù)示例,需要的朋友可以參考下2014-03-03Android webview與js交換JSON對(duì)象數(shù)據(jù)示例
js主動(dòng)調(diào)用android的對(duì)象方式,android也無法返回給js一個(gè)jsonobject,需要js做一下轉(zhuǎn)換,具體代碼如下,感興趣的朋友可以參考下哈2013-06-06Linux系統(tǒng)下安裝android sdk的方法步驟
這篇文章主要介紹了Linux系統(tǒng)下安裝android sdk的方法步驟,文中介紹的非常詳細(xì),相信對(duì)大家具有一定的參考價(jià)值,需要的朋友可以們下面來一起看看吧。2017-03-03Android如何實(shí)現(xiàn)接收和發(fā)送短信
這篇文章主要為大家詳細(xì)介紹了Android如何實(shí)現(xiàn)接收和發(fā)送短信,具有一定的實(shí)用性,感興趣的小伙伴們可以參考一下2016-08-08