自訂控制項詳解(五):onMeasure()、onLayout(),onmeasureonlayout

來源:互聯網
上載者:User

自訂控制項詳解(五):onMeasure()、onLayout(),onmeasureonlayout

前言:

  自訂控制項的三大方法:

測量: onMeasure():  測量自己的大小,為正式布局提供建議 布局: onLayout():   使用layout()函數對所有子控制項布局繪製: onDraw():     根據布局的位置繪圖 

      onDraw() 裡面是繪製的操作,可以看下其他的文章,下面來瞭解 onMeasure()和onLayout()方法。

 

一、onMeasure()、測量

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)  

參數即父類傳過來的兩個寬高的"建議值",即把當前view的高設定為:heightMeasureSpec ;寬設定為:widthMeasureSpec

這個參數不是簡單的整數類型,而是2位整數(模式類型)和30位整數(實際數值) 的組合

 

其中模式分為三種:

①、UNSPECIFIED(未指定),父元素部隊自元素施加任何束縛,子項目可以得到任意想要的大小;UNSPECIFIED=00000000000000000000000000000000

②、EXACTLY(完全),父元素決定自元素的確切大小,子項目將被限定在給定的邊界裡而忽略它本身大小;EXACTLY =01000000000000000000000000000000
③、AT_MOST(至多),子項目至多達到指定大小的值。 他們對應的二進位值分別是: AT_MOST =10000000000000000000000000000000 

最前面兩位代表模式,分別對應十進位的0,1,2;

 

擷取模式int值 和 擷取數值int值的方法:

  1. int measureWidth = MeasureSpec.getSize(widthMeasureSpec);  
  2. int measureHeight = MeasureSpec.getSize(heightMeasureSpec);  
  3. int measureWidthMode = MeasureSpec.getMode(widthMeasureSpec);  
  4. int measureHeightMode = MeasureSpec.getMode(heightMeasureSpec); 

模式的值有:

MeasureSpec.AT_MOST       = 2MeasureSpec.EXACTLY       = 1MeasureSpec.UNSPECIFIED   = 0

 

上面我們知道了 onMeasure(int widthMeasureSpec, int heightMeasureSpec) 方法參數的意義

下面瞭解參數對應的三個模式分別對應的意義:

每一個模式都對應的xml布局中的一個值

wrap_content   --- MeasureSpec.AT_MOSTmatch_parent   --- MeasureSpec.EXACTLY具體值          --- MeasureSpec.EXACTLY

 

注意:當模式是MeasureSpec.AT_MOST時,即wrap_content時,需要將大小設定一個數值。

 

 

二、onLayout() 、 布局

首先先瞭解幾個需要用到的方法:

  (1)、

      這個方法和onMeasure()方法類似。其實這個方法的作用就是 設定當前View的寬高。

  (2)、

      這個方法就和方法類似了,不過少了第一個參數boolean changed

      這個方法的目的是用於當前ViewGroup中的子控制項的布局

 

  再看方法,只要是繼承ViewGroup的類都必須要重寫該方法,來實現該控制項內部子控制項的布局情況。

  我們寫一個自訂類繼承ViewGroup實現Linearlayout垂直排列的效果看下:

  public class XViewGroup extends ViewGroup{    public XViewGroup(Context context) {        super(context);    }    public XViewGroup(Context context, AttributeSet attrs) {        super(context, attrs);    }    public XViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int measureWidth = MeasureSpec.getSize(widthMeasureSpec);        int measureHeight = MeasureSpec.getSize(heightMeasureSpec);        int measureWidthMode = MeasureSpec.getMode(widthMeasureSpec);        int measureHeightMode = MeasureSpec.getMode(heightMeasureSpec);     
      
     // 計算所有子控制項需要用到的寬高 int height = 0; //記錄根容器的高度 int width = 0; //記錄根容器的寬度 int count = getChildCount(); //記錄容器內的子控制項個數 for (int i=0;i<count;i++) { //測量子控制項 View child = getChildAt(i); measureChild(child, widthMeasureSpec, heightMeasureSpec); //獲得子控制項的高度和寬度 int childHeight = child.getMeasuredHeight(); int childWidth = child.getMeasuredWidth(); //得到最大寬度,並且累加高度 height += childHeight; width = Math.max(childWidth, width); }     // 設定當前View的寬高 setMeasuredDimension((measureWidthMode == MeasureSpec.EXACTLY) ? measureWidth: width, (measureHeightMode == MeasureSpec.EXACTLY) ? measureHeight: height); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int top = 0; int count = getChildCount(); for (int i=0;i<count;i++) { View child = getChildAt(i); int childHeight = child.getMeasuredHeight(); int childWidth = child.getMeasuredWidth(); //該子控制項在父容器的位置 , 高度是之前所有子控制項的高度和開始 ,從上往下排列,就實現了類似Linearlayout布局垂直排列的布局 child.layout(0, top, childWidth, top + childHeight); //以父容器左上方為原點進行布局 top += childHeight; } } }

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.