Android 自定义百分比布局

效果图:
这里写图片描述
思路:
一、编写xml文件,声明自定义属性
二、继承RelativeLayout
三、根据自定义ViewGroup的思想咱们通常会在继承以后,建立构造器,而后重写onMeasure、onLayout和onDraw三个方法。这里对onLayout和onDraw方法都不须要进行特别的操做。由于百分比布局,是以该布局做为容器,子控件的宽度跟高度以百分比布局为参考设定。好比你的容器宽200px,子控件设置占容器宽度的0.5则子控件宽度为100px。因此主要是在onMeasure方法中编写代码。
为了支持margin、padding属性重写了generateLayoutParams()方法,并经过返回new LayoutParams(getContext(),attrs)对象解析到自定义的属性,最后在omMeasure方法中获取容器宽和高,遍历子控件,若是子控件的widthPercent或者heightPercent属性不为0就为该子控件的宽度或者高度从新赋值
四、使用自定义布局
代码:
一、声明自定义属性:java

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="percentLayout">
        <attr name="widthPercent" format="float"></attr>
        <attr name="heightPercent" format="float"></attr>
    </declare-styleable>
</resources>

二、自定义百分比布局
(1)定义属性、解析属性 、返回给generateLayoutParams
(2)onMeasure中对子控件遍历、获取属性值、设置宽度或者高度android

public class PercentLayout extends RelativeLayout {
    public PercentLayout(Context context) {
        super(context);
    }

    public PercentLayout(Context context, AttributeSet attrs) {

        super(context, attrs);

    }
    //测量容器宽高
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = View.MeasureSpec.getSize(widthMeasureSpec);
        int height=View.MeasureSpec.getSize(heightMeasureSpec);
        //测量出子控件的宽高
        int childcount=getChildCount();
        for (int i=0;i<childcount;i++){
            View child=this.getChildAt(i);
            LayoutParams params= (LayoutParams) child.getLayoutParams();
            //默认不设置是为0
            float widthPercent=0;
            float heightPercent=0;
                  if(params instanceof PercentLayout.LayoutParams){
                widthPercent=((LayoutParams) params).getWidthPercent();
                heightPercent=((LayoutParams) params).getHeightPercent();
                if(widthPercent!=0){
                //不为0时从新设置宽度
                  params.width= (int) (width*widthPercent);
                }
                if(heightPercent!=0){
                    params.height= (int) (height*heightPercent);
                }
            }

        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

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


    public  static  class LayoutParams extends RelativeLayout.LayoutParams{
        //定义属性
        private float widthPercent;
        private float heightPercent;

        public float getWidthPercent() {
            return widthPercent;
        }

        public float getHeightPercent() {
            return heightPercent;
        }

        public LayoutParams(Context context, AttributeSet attrs) {
            super(context, attrs);
            //解析本身定义的属性
            TypedArray array=context.obtainStyledAttributes(attrs,R.styleable.percentLayout);
             widthPercent=array.getFloat(R.styleable.percentLayout_widthPercent,widthPercent);
             heightPercent=array.getFloat(R.styleable.percentLayout_heightPercent,getHeightPercent());
            array.recycle();

        }

        public LayoutParams(int w, int h) {
            super(w, h);
        }

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

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


    }
    //用于对子控件进行布局
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
    }
}

三、使用
注意:添加这行代码(AndroidStudio以下,若是是ecplise:xmlns:app="http://schemas.android.com/apk/res/包名+类名):web

xmlns:app="http://schemas.android.com/apk/res-auto"

使用例子:bash

<com.df.percentlayout.androidpercentlayout.PercentLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
  >
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:widthPercent="0.8"
        app:heightPercent="0.8"
        android:layout_centerInParent="true"
        android:background="#00ff00"
        android:text="Hello World!" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:widthPercent="0.5"
        app:heightPercent="0.3"
        android:layout_centerInParent="true"
        android:background="#ff0000"
        android:text="Hello World!" />

</com.df.percentlayout.androidpercentlayout.PercentLayout>