Android 自訂ViewGroup(自訂版面配置容器)

來源:互聯網
上載者:User

標籤:

1、先建立一個控制項類間接或者直接繼承ViewGroup類

2、重載onMeasure方法來測量控制項  

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)

3、重載onLayout方法來布局子空間  

protected void onLayout(boolean changed, int l, int t, int r, int b)

4、重載返回ViewGroup.LayoutParams的方法    

public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs)

protected ViewGroup.LayoutParams generateDefaultLayoutParams()

protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p)

 

下面實現一個圓形布局的容器

package com.example.asdlon.circleviewgroupdemo;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.View;import android.view.ViewGroup;public class CircleLayout extends ViewGroup{    private static final String TAG = "CircleLayout";    public CircleLayout(Context context, AttributeSet attrs, int defStyle)    {        super(context, attrs, defStyle);    }    public CircleLayout(Context context)    {        super(context);    }    public CircleLayout(Context context, AttributeSet attrs)    {        super(context, attrs);    }    public int Radius=50;    /**     * 計算所有ChildView的寬度和高度 然後根據ChildView的計算結果,設定自己的寬和高     */    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)    {        /**         * 獲得此ViewGroup上級容器為其推薦的寬和高,以及計算模式         */        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int heightMode = MeasureSpec.getMode(heightMeasureSpec);        int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);        int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);        Log.e(TAG, (heightMode == MeasureSpec.UNSPECIFIED) + "," + sizeHeight                + "," + getLayoutParams().height);        // 計算出所有的childView的寬和高        measureChildren(widthMeasureSpec, heightMeasureSpec);        /**         * 記錄如果是wrap_content是設定的寬和高         */        int width = 0;        int height = 0;        int cCount = getChildCount();        int cWidth = 0;        int cHeight = 0;        MarginLayoutParams cParams = null;        //最大的寬度的變數        int maxElementWidth = 0;        //遍曆所有的子物件,並調用子物件的Measure方法進行測量,取出最大的寬度的子物件        for (int i = 0; i < cCount; i++) {            //測量子物件            View childView = getChildAt(i);            cWidth = childView.getMeasuredWidth();            maxElementWidth = Math.max(cWidth, sizeWidth);        }        //兩個半徑的大小和最大的寬度的兩倍最為面板的寬度        int panelWidth = 2 * this.Radius + 2 * maxElementWidth;        //取面板的所分配的高度寬度和計算出來的寬度的最小值最為面板的實際大小        int width2 = Math.min(panelWidth, sizeWidth);        int heigh2 = Math.min(panelWidth, sizeWidth);        setMeasuredDimension(width2, heigh2);    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b)    {        int cCount = getChildCount();        int cWidth = 0;        int cHeight = 0;        MarginLayoutParams cParams = null;        /**         * 遍曆所有childView根據其寬和高,以及margin進行布局         */        //當前的角度,從0開始排列        double degree = 0;        //計算每個子物件所佔用的角度大小        double degreeStep = (double)360 / cCount;        //計算        int pWidth= getWidth();        double mX = pWidth  / 2;       int pHeight= getHeight();        double mY = pHeight / 2;        //遍曆所有的子物件進行排列        for (int i = 0; i < cCount; i++) {            View childView = getChildAt(i);            cWidth = childView.getMeasuredWidth();            cHeight = childView.getMeasuredHeight();            cParams = (MarginLayoutParams) childView.getLayoutParams();            //把角度轉換為弧度單位            double angle = Math.PI * degree / 180.0;            //根據弧度計算出圓弧上的x,y的座標值            double x = Math.cos(angle) * this.Radius;            double y = Math.sin(angle) * this.Radius;            childView.setPivotX(0);            childView.setPivotY(0);            childView.setRotation((float)degree);            childView.layout((int)(mX + x), (int)(mY + y),(int)(mX + x+cWidth), (int)(mY + y+cHeight));            Log.e(TAG, "mX"+(int)mX+"mY"+(int)mY+"x"+(int)x+"y"+(int)y+"degree"+degree+"cWidth"+cWidth+"cHeight"+cHeight);            //角度遞增            degree += degreeStep;        }    }    @Override    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs)    {        return new MarginLayoutParams(getContext(), attrs);    }    @Override    protected ViewGroup.LayoutParams generateDefaultLayoutParams()    {        Log.e(TAG, "generateDefaultLayoutParams");        return new MarginLayoutParams(LayoutParams.MATCH_PARENT,                LayoutParams.MATCH_PARENT);    }    @Override    protected ViewGroup.LayoutParams generateLayoutParams(            ViewGroup.LayoutParams p)    {        Log.e(TAG, "generateLayoutParams p");        return new MarginLayoutParams(p);    }}
    <com.example.asdlon.circleviewgroupdemo.CircleLayout        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="#AA333333" >        <TextView            android:layout_width="150dp"            android:layout_height="50dp"            android:background="#E5ED05"            android:text="0000000"            android:textColor="#FFFFFF"            android:textSize="22sp"            android:textStyle="bold" />        <TextView            android:layout_width="150dp"            android:layout_height="50dp"            android:background="#00ff00"            android:text="1111111"            android:textColor="#FFFFFF"            android:textSize="22sp"            android:textStyle="bold" />        <TextView            android:layout_width="150dp"            android:layout_height="50dp"            android:background="#ff0000"            android:text="2222222222"            android:textColor="#FFFFFF"            android:textSize="22sp"            android:textStyle="bold" />        <TextView            android:layout_width="150dp"            android:layout_height="50dp"            android:background="#0000ff"            android:gravity="center"            android:text="333333"            android:textColor="#FFFFFF"            android:textSize="22sp"            android:textStyle="bold" />    </com.example.asdlon.circleviewgroupdemo.CircleLayout>

 

Android 自訂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.