国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android View.onMeasure方法詳解及實例

2019-12-12 02:55:46
字體:
來源:轉載
供稿:網友

Android View.onMeasure方法詳解及實例

View在屏幕上顯示出來要先經過measure(計算)和layout(布局).

1、什么時候調用onMeasure方法?

當控件的父元素正要放置該控件時調用.父元素會問子控件一個問題,“你想要用多大地方啊?”,然后傳入兩個參數――widthMeasureSpec和heightMeasureSpec.

這兩個參數指明控件可獲得的空間以及關于這個空間描述的元數據.

更好的方法是你傳遞View的高度和寬度到setMeasuredDimension方法里,這樣可以直接告訴父控件,需要多大地方放置子控件.

  接下來的代碼片段給出了如何重寫onMeasure.注意,調用的本地空方法是來計算高度和寬度的.它們會譯解widthHeightSpec和heightMeasureSpec值,并計算出合適的高度和寬度值.

@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int measuredHeight = measureHeight(heightMeasureSpec);int measuredWidth = measureWidth(widthMeasureSpec);setMeasuredDimension(measuredHeight, measuredWidth);}private int measureHeight(int measureSpec) {// Return measured widget height.}private int measureWidth(int measureSpec) {// Return measured widget width.}

邊界參數――widthMeasureSpec和heightMeasureSpec ,效率的原因以整數的方式傳入。在它們使用之前,首先要做的是使用MeasureSpec類的靜態方法getMode和getSize來譯解,如下面的片段所示:

int specMode = MeasureSpec.getMode(measureSpec);int specSize = MeasureSpec.getSize(measureSpec);

依據specMode的值,(MeasureSpec有3種模式分別是UNSPECIFIED, EXACTLY和AT_MOST)

  • 如果是AT_MOST,specSize 代表的是最大可獲得的空間;
  • 如果是EXACTLY,specSize 代表的是精確的尺寸;
  • 如果是UNSPECIFIED,對于控件尺寸來說,沒有任何參考意義。

2、那么這些模式和我們平時設置的layout參數fill_parent, wrap_content有什么關系呢?

經過代碼測試就知道,當我們設置width或height為fill_parent時,容器在布局時調用子 view的measure方法傳入的模式是EXACTLY,因為子view會占據剩余容器的空間,所以它大小是確定的。

而當設置為 wrap_content時,容器傳進去的是AT_MOST, 表示子view的大小最多是多少,這樣子view會根據這個上限來設置自己的尺寸。當子view的大小設置為精確值時,容器傳入的是EXACTLY, 而MeasureSpec的UNSPECIFIED模式目前還沒有發現在什么情況下使用。 

   View的onMeasure方法默認行為是當模式為UNSPECIFIED時,設置尺寸為mMinWidth(通常為0)或者背景drawable的最小尺寸,當模式為EXACTLY或者AT_MOST時,尺寸設置為傳入的MeasureSpec的大小。 

   有個觀念需要糾正的是,fill_parent應該是子view會占據剩下容器的空間,而不會覆蓋前面已布局好的其他view空間,當然后面布局子 view就沒有空間給分配了,所以fill_parent屬性對布局順序很重要。以前所想的是把所有容器的空間都占滿了,難怪google在2.2版本里把fill_parent的名字改為match_parent.

  在兩種情況下,你必須絕對的處理這些限制。在一些情況下,它可能會返回超出這些限制的尺寸,在這種情況下,你可以讓父元素選擇如何對待超出的View,使用裁剪還是滾動等技術。

  接下來的框架代碼給出了處理View測量的典型實現:

java代碼:

@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int measuredHeight = measureHeight(heightMeasureSpec);int measuredWidth = measureWidth(widthMeasureSpec);setMeasuredDimension(measuredHeight, measuredWidth);}private int measureHeight(int measureSpec) {int specMode = MeasureSpec.getMode(measureSpec);int specSize = MeasureSpec.getSize(measureSpec);// Default size if no limits are specified.int result = 500;if (specMode == MeasureSpec.AT_MOST){// Calculate the ideal size of your// control within this maximum size.// If your control fills the available// space return the outer bound.result = specSize;}else if (specMode == MeasureSpec.EXACTLY){// If your control can fit within these bounds return that value.result = specSize;}return result;}private int measureWidth(int measureSpec) {int specMode = MeasureSpec.getMode(measureSpec);int specSize = MeasureSpec.getSize(measureSpec);// Default size if no limits are specified.int result = 500;if (specMode == MeasureSpec.AT_MOST){// Calculate the ideal size of your control// within this maximum size.// If your control fills the available space// return the outer bound.result = specSize;}else if (specMode == MeasureSpec.EXACTLY){// If your control can fit within these bounds return that value.result = specSize;}return result;}

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 金寨县| 景洪市| 石棉县| 平塘县| 炎陵县| 长丰县| 乡宁县| 西盟| 饶阳县| 青海省| 志丹县| 永康市| 中牟县| 罗江县| 井研县| 灵川县| 宝山区| 政和县| 宣化县| 墨竹工卡县| 武乡县| 富裕县| 津南区| 连城县| 舒兰市| 周至县| 靖江市| 广汉市| 马公市| 祁门县| 南川市| 阿克陶县| 屏南县| 宿迁市| 涞源县| 通山县| 来凤县| 孝义市| 古丈县| 乌海市| 北票市|