Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android View如何測量

Android View如何測量

編輯:關於Android編程

        對於Android View的測量,我們一句話總結為:"給我位置和大小,我就知道您長到那裡"。

  為了讓大家更好的理解這個結論,我這裡先講一個日常生活中的小故事:不知道大家玩過"瞎子畫畫"的游戲沒,一個人蒙上眼睛,拿筆去畫板上畫一些指定的圖案,另外一個人則充當他的"眼睛",通過語言告訴他在畫板那個位置畫一個多大的圖案。倘若,這個人不告訴那個蒙著眼睛的人,在那個畫一個多大的圖案。那麼這個蒙著眼睛的人此時真是"河裡趕大車----------沒轍"。其實,Android就是這個蒙著眼睛的人,我們必須精確地告訴他如何去畫,它才能畫出你所想要的圖形。

  大家是不是對Android布局的測量進行現實世界進行類比了。為了實現View具體布局在哪兒,Android設計了一個短小精悍又功能強大的類——measureSpec類。這樣媽媽再也不用擔心我不會測量View了。那麼,MeasureSpec到底是個什麼鬼了。MeasureSpec,歸根結底是一個32位的int值。其中高2位表示測量的模式,低30位表示測量View的大小。這樣做有什麼好處。這樣做通過位運算來提高運行效率。

  要了解MeasureSpec這個類的來弄去脈的話,務必要對測量的三種模式了解。

  1.EXACTLY(精准的)

  當您設置View的layout_height屬性或layout_width屬性為確定的值或者為match_parent(填充父容器)時候,系統就將View測量模式設置為EXACTLY模式。

  2.AT_MOST(最大值)

  即布局為最大值模式,那麼什麼時候系統會將View調整為AT_MOST模式了,即當您設置View的layout_height屬性或layout_width屬性為wrap_content(包裹內容)時候。

  3.UNSPECIFIED(未確定)

  即沒有確定,沒有指定大小測量模式,view即“心有多大,舞台就有多大"。這個方法,一般在自定義控件中才能用到。

  View測量的時候,默認是EXACTLY模式,也許你會感到納悶,TextView,EditText這些控件,他怎麼就支持wrap_content屬性了,難道他重寫OnMeasure方法,是的,他們都重寫OnMeasure方法。這就是為什麼我們在自定義控件的時候,如果要布局支持wrap_content屬性,就需要重寫onMeasure方法,來指定wrap_content為確切的大小。

  這個關於測量模式的思維導圖應該是這樣的:

  

  我們知道這麼多理論的知識,是不是覺得即枯燥乏味又覺得然並卵。好吧,我們就直接上代碼,在代碼中解釋MeasureSpec如何獲取測量模式和測量的大小。源代碼如下:

   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>

運行效果如下所示:

  通過這個短小精悍的例子,充分證明這樣一個結論:View測量的時候,默認是EXACTLY模式,你不重寫OnMeasure方法,即使設置wrap_content屬性,他也是填充父容器。

  那麼,就通過MeasureSpec這個萬金油類來重寫一下OnMeasure方法。相應源代碼如下:

  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;
  }

運行效果如下:

  同樣的例子,我們只不過是重寫了OnMeasure方法,通過MeasureSpec.getMode(measureSpec)獲取測量模式的時候,通過MeasureSpec.getSize(measureSpec)獲取控件尺寸。判斷當布局屬性為wrap_content,指定為一確切值,這時,控件就符合wrap_content屬性。

以上就是本文的全部內容,希望對大家的學習有所幫助。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved