天天看點

Android 手寫百分比布局

百分比布局:通過設定百分比參數,自動适應手機螢幕,有時候還是比較實用的!

思路:

1:Android 自定義xmlns,百分比布局有2個自定義參數 所有要自定義 ximls

2:自定義百分比布局 繼承 相對布局,重寫LayoutParams 内部類(這裡增加 2個百分比參數)

3:重寫 onMeasure( )方法,在onMeasure 裡擷取容器的寬高,然後獲得所有子控件,判斷子空間的 LayoutParams 是否為 百分比布局的 LayoutParams,相同則 讀取子控件的 長寬百分比 參數,然後計算出實際的長寬參數!

實作:

1: 自定義xmlns,首先 在 res下建立 attr.xml檔案 聲明一個styleable

<resources>
    <declare-styleable name="percentLayout">
        <attr name="layout_widthPercent" format = "float"> </attr>
         <attr name="layout_heightPercent" format = "float"> </attr>
    </declare-styleable>

</resources>
           

在 布局檔案中添加自定義屬性:

eclipse 這樣寫

http://schemas.android.com/apk/res/你的自定義View所在的包路徑.
           

stuido 使用統一預設的

然後 在需要使用的子控件添加 百分比屬性

<Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="nice" 
        app:layout_widthPercent="0.6"
        app:layout_heightPercent="0.8"
        android:background="#00ff00"
        />
           

整個自定義 xmlns 就完成了,接下來實作自定義控件

public class PercentLayout extends RelativeLayout{


    public PercentLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // TODO Auto-generated constructor stub
    }

    public PercentLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    public PercentLayout(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    /***
     * 測量容器的寬高
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // 擷取容器的寬高
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        //測量子控件的寬高,然後進行改變

        int childCount = getChildCount();
        for (int i = ; i < childCount; i++) {
            View child = getChildAt(i);
            float widthPercent = ;
            float heightPercent = ;
            //獲得子控件的布局參數
            ViewGroup.LayoutParams params = child.getLayoutParams();
            //判斷是否為百分比布局
            if(params instanceof LayoutParams){
                widthPercent = ((LayoutParams) params).getWidthPercent();
                heightPercent = ((LayoutParams) params).getHeightPerccent();
            }
            if(widthPercent!=){
                params.width = (int) (width*widthPercent);
                params.height = (int) (height*heightPercent);
            }
        }

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    /***
     * 排列擺放子控件
     */
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
    }

    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new LayoutParams(getContext(), attrs);
    }

    //布局參數内部類,xml解析會自動關聯對應的布局參數
    class LayoutParams extends RelativeLayout.LayoutParams{
        private float widthPercent;
        private float heightPerccent;
        public float getWidthPercent() {
            return widthPercent;
        }

        public void setWidthPercent(float widthPercent) {
            this.widthPercent = widthPercent;
        }

        public float getHeightPerccent() {
            return heightPerccent;
        }

        public void setHeightPerccent(float heightPerccent) {
            this.heightPerccent = heightPerccent;
        }

        public LayoutParams(Context arg0, AttributeSet arg1) {
            super(arg0, arg1);
            TypedArray array = arg0.obtainStyledAttributes(arg1, R.styleable.percentLayout);
            widthPercent = array.getFloat(R.styleable.percentLayout_layout_widthPercent, widthPercent);
            heightPerccent = array.getFloat(R.styleable.percentLayout_layout_heightPercent, heightPerccent);
            array.recycle();
        }

        public LayoutParams(int arg0, int arg1) {
            super(arg0, arg1);
        }

        public LayoutParams(ViewGroup.LayoutParams arg0) {
            super(arg0);
        }


        public LayoutParams(MarginLayoutParams arg0) {
            super(arg0);
        }

    }


}
           

這個自定義控件代碼,下面是 整個頁面布局

<go.lqb.com.nettest.dn_sindy_layout.PercentLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="400dp"
    android:layout_height="600dp"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    >

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="nice" 
        app:layout_widthPercent="0.6"
        app:layout_heightPercent="0.8"
        android:background="#00ff00"
        />

</go.lqb.com.nettest.dn_sindy_layout.PercentLayout>