Android View如何測(cè)量
對(duì)于Android View的測(cè)量,我們一句話(huà)總結(jié)為:"給我位置和大小,我就知道您長(zhǎng)到那里"。
為了讓大家更好的理解這個(gè)結(jié)論,我這里先講一個(gè)日常生活中的小故事:不知道大家玩過(guò)"瞎子畫(huà)畫(huà)"的游戲沒(méi),一個(gè)人蒙上眼睛,拿筆去畫(huà)板上畫(huà)一些指定的圖案,另外一個(gè)人則充當(dāng)他的"眼睛",通過(guò)語(yǔ)言告訴他在畫(huà)板那個(gè)位置畫(huà)一個(gè)多大的圖案。倘若,這個(gè)人不告訴那個(gè)蒙著眼睛的人,在那個(gè)畫(huà)一個(gè)多大的圖案。那么這個(gè)蒙著眼睛的人此時(shí)真是"河里趕大車(chē)----------沒(méi)轍"。其實(shí),Android就是這個(gè)蒙著眼睛的人,我們必須精確地告訴他如何去畫(huà),它才能畫(huà)出你所想要的圖形。
大家是不是對(duì)Android布局的測(cè)量進(jìn)行現(xiàn)實(shí)世界進(jìn)行類(lèi)比了。為了實(shí)現(xiàn)View具體布局在哪兒,Android設(shè)計(jì)了一個(gè)短小精悍又功能強(qiáng)大的類(lèi)——measureSpec類(lèi)。這樣?jì)寢屧僖膊挥脫?dān)心我不會(huì)測(cè)量View了。那么,MeasureSpec到底是個(gè)什么鬼了。MeasureSpec,歸根結(jié)底是一個(gè)32位的int值。其中高2位表示測(cè)量的模式,低30位表示測(cè)量View的大小。這樣做有什么好處。這樣做通過(guò)位運(yùn)算來(lái)提高運(yùn)行效率。
要了解MeasureSpec這個(gè)類(lèi)的來(lái)弄去脈的話(huà),務(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(未確定)
即沒(méi)有確定,沒(méi)有指定大小測(cè)量模式,view即“心有多大,舞臺(tái)就有多大"。這個(gè)方法,一般在自定義控件中才能用到。
View測(cè)量的時(shí)候,默認(rèn)是EXACTLY模式,也許你會(huì)感到納悶,TextView,EditText這些控件,他怎么就支持wrap_content屬性了,難道他重寫(xiě)OnMeasure方法,是的,他們都重寫(xiě)OnMeasure方法。這就是為什么我們?cè)谧远x控件的時(shí)候,如果要布局支持wrap_content屬性,就需要重寫(xiě)onMeasure方法,來(lái)指定wrap_content為確切的大小。
這個(gè)關(guān)于測(cè)量模式的思維導(dǎo)圖應(yīng)該是這樣的:

我們知道這么多理論的知識(shí),是不是覺(jué)得即枯燥乏味又覺(jué)得然并卵。好吧,我們就直接上代碼,在代碼中解釋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)行效果如下所示:

通過(guò)這個(gè)短小精悍的例子,充分證明這樣一個(gè)結(jié)論:View測(cè)量的時(shí)候,默認(rèn)是EXACTLY模式,你不重寫(xiě)OnMeasure方法,即使設(shè)置wrap_content屬性,他也是填充父容器。
那么,就通過(guò)MeasureSpec這個(gè)萬(wàn)金油類(lèi)來(lái)重寫(xiě)一下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)行效果如下:

同樣的例子,我們只不過(guò)是重寫(xiě)了OnMeasure方法,通過(guò)MeasureSpec.getMode(measureSpec)獲取測(cè)量模式的時(shí)候,通過(guò)MeasureSpec.getSize(measureSpec)獲取控件尺寸。判斷當(dāng)布局屬性為wrap_content,指定為一確切值,這時(shí),控件就符合wrap_content屬性。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。
相關(guān)文章
Android開(kāi)發(fā)簡(jiǎn)易音樂(lè)播放器
這篇文章主要為大家詳細(xì)介紹了Android開(kāi)發(fā)簡(jiǎn)易音樂(lè)播放器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12
Android自定義view實(shí)現(xiàn)TextView方形輸入框
這篇文章主要為大家詳細(xì)介紹了Android自定義view實(shí)現(xiàn)TextView方形輸入框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06
Android實(shí)現(xiàn)實(shí)時(shí)通信示例
本篇文章主要介紹了Android實(shí)時(shí)通信示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-03-03
android中ProgressDialog與ProgressBar的使用詳解
本篇文章是對(duì)android中ProgressDialog與ProgressBar的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
Android 開(kāi)發(fā)實(shí)例簡(jiǎn)單涂鴉板
本文主要介紹 Android 簡(jiǎn)單涂鴉板,這里提供了代碼示例和實(shí)現(xiàn)效果圖,有興趣的小伙伴可以參考下2016-08-08
讀寫(xiě)Android中assets目錄下的文件的方法詳解
這篇文章主要介紹了讀寫(xiě)Android中assets目錄下的文件的方法詳解,assets和res/raw工程目錄下都可以放一些文件,這些文件將被打包到APK中應(yīng)用使用,需要的朋友可以參考下2016-04-04
Android實(shí)現(xiàn)簡(jiǎn)單動(dòng)態(tài)搜索功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)簡(jiǎn)單動(dòng)態(tài)搜索功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05

