Android 自訂View、ViewGroup和自訂屬性

來源:互聯網
上載者:User

標籤:意義   java   測量   apple   xml檔案   根據   size   change   pixel   

一、Android自訂view屬性

1.在res/values/styles.xml檔案裡面聲明一個我們自訂的屬性:

<resources>    <!--name為聲明的"屬性集合"名,可以隨便取,但是最好是設定為跟我們的View一樣的名稱-->    <declare-styleable name="CircleView">        <!--聲明我們的屬性,名稱為default_size,取實值型別為尺寸類型(dp,px等)-->        <attr name="radius" format="dimension"></attr>        <attr name="circle_color" format="color"></attr>    </declare-styleable></resources>

 

2.在自訂View中擷取對應設定的屬性值
public CircleView(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);        //即屬性集合的標籤,在R檔案中名稱為R.styleable+name        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleView);        //第一個參數為屬性集合裡面的屬性,R檔案名稱:R.styleable+屬性集合名稱+底線+屬性名稱        //第二個參數為,如果沒有設定這個屬性,則設定的預設的值        radius = typedArray.getDimensionPixelOffset(R.styleable.CircleView_radius, 20);        color = typedArray.getColor(R.styleable.CircleView_circle_color, 000000);        //最後記得將TypedArray對象回收        typedArray.recycle();    }

 

3.在xml檔案中設定屬性值(1)首先需要定義命名空間 xmlns:rc="http://schemas.android.com/apk/res-auto"(2)設定屬性值 rc:radius   rc:circle_color
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:rc="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context="com.ruanchao.todaynews.UserViewActivity">     <com.ruanchao.todaynews.view.CircleView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        rc:radius="50dp"        rc:circle_color="#FF69B4"/> </LinearLayout>

 

二、Android自訂View 1.onMeasure
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
參數中的 widthMeasureSpecheightMeasureSpec包含了兩層資訊:測量模式和測量尺寸   (1)測量模式:
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
測量模式 表示意思
UNSPECIFIED 父容器沒有對當前View有任何限制,當前View可以任意取尺寸(match_parent)
EXACTLY 當前的尺寸就是當前View應該取的尺寸(xml配置固定值)
AT_MOST 當前尺寸是當前View能取的最大尺寸(wrap_content)
(2)尺寸大小:
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
範例程式碼: 
private int getMySize(int defaultSize, int measureSpec) {        int mySize = defaultSize;         int mode = MeasureSpec.getMode(measureSpec);        int size = MeasureSpec.getSize(measureSpec);         switch (mode) {            case MeasureSpec.UNSPECIFIED: {//如果沒有指定大小,就設定為預設大小                mySize = defaultSize;                break;            }            case MeasureSpec.AT_MOST: {//如果測量模式是最大取值為size                //我們將大小取最大值,你也可以取其他值                mySize = size;                break;            }            case MeasureSpec.EXACTLY: {//如果是固定的大小,那就不要去改變它                mySize = size;                break;            }        }        return mySize;} @Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int width = getMySize(100, widthMeasureSpec);        int height = getMySize(100, heightMeasureSpec);         if (width < height) {            height = width;        } else {            width = height;        }         setMeasuredDimension(width, height);}
<com.hc.studyview.MyView        android:layout_width="match_parent"        android:layout_height="100dp"        android:background="#ff0000" />
 2.onDraw 直接在畫板Canvas對象上繪製(1)invalidate方法會執行onDraw過程,只能在UI線程調用(2)postInvalidate 可以在非UI線程調用,省去了Handler訊息調用(3)RequestLayout 會執行onMeasure,onLayout ,onDraw三、Android自訂ViewGroup自訂ViewGruup要經曆以下幾步:1、根據各個子View的大小,確定ViewGroup大小(重寫onMeasure()方法)2、在ViewGroup中進行View的擺放(重寫onLayout()方法) 範例程式碼:自訂ViewGroup實現LinearLayout布局第一步:確定ViewGroup大小 
@Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int with = MeasureSpec.getSize(widthMeasureSpec);        int height =  MeasureSpec.getSize(heightMeasureSpec);        int withMode = MeasureSpec.getMode(widthMeasureSpec);        int heigthMode = MeasureSpec.getMode(heightMeasureSpec);        if (getChildCount() == 0) {//如果沒有子View,當前ViewGroup沒有存在的意義,不用佔用空間            setMeasuredDimension(0, 0);            return;        }        if (withMode == MeasureSpec.AT_MOST && heigthMode == MeasureSpec.AT_MOST){            //高度累加,寬度取最大            setMeasuredDimension(getMaxChildWidth(),getTotleHeight());        }else if (heigthMode == MeasureSpec.AT_MOST){            setMeasuredDimension(with,getTotleHeight());        }else if (withMode == MeasureSpec.AT_MOST){            setMeasuredDimension(getMaxChildWidth(),height);        }    }     /***     * 擷取子View中寬度最大的值     */    private int getMaxChildWidth() {        int childCount = getChildCount();        int maxWidth = 0;        for (int i = 0; i < childCount; i++) {            View childView = getChildAt(i);            if (childView.getMeasuredWidth() > maxWidth) {                maxWidth = childView.getMeasuredWidth();            }        }        return maxWidth;    }     /***     * 將所有子View的高度相加     **/    private int getTotleHeight() {        int childCount = getChildCount();        int height = 0;        for (int i = 0; i < childCount; i++) {            View childView = getChildAt(i);            height += childView.getMeasuredHeight();        }        return height;    }

 

第二步:在ViewGroup中進行子View的擺放
 @Override    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {        int count = getChildCount();        int currentHeigth = 0;        //將子View逐個擺放        for (int i = 0; i < count; i++) {            View child = getChildAt(i);            int childHeigth = child.getMeasuredHeight();            child.layout(left, currentHeigth, right + child.getMeasuredWidth(), currentHeigth + childHeigth);            currentHeigth += childHeigth;        }     }
測試xml
<com.rc.studyview.MyViewGroup        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="#ff9900">         <Button            android:layout_width="100dp"            android:layout_height="wrap_content"            android:text="btn" />         <Button            android:layout_width="200dp"            android:layout_height="wrap_content"            android:text="btn" />         <Button            android:layout_width="50dp"            android:layout_height="wrap_content"              android:text="btn" />     </com.rc.studyview.MyViewGroup>

 

Android 自訂View、ViewGroup和自訂屬性

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.