android自定义View(2):实现百分比自适应布局

来源:互联网 发布:sql server 注释代码 编辑:程序博客网 时间:2024/04/28 09:52

android界面适配难是历史原因,我们只能想办法解决。github上面已有一些布局自适应的解决方案,今天我分享的是自定义控件:RelativieLayout自适应百分比宽高。直接上菜。

一,实现的效果图

宽高都是50%自适应
眼见为实,截图所示,宽高都是50%,实现了自适应

二,实现的原理

其实很简单,就是自定义两个属性:宽和高的百分比,让自定义的view继承 RelativeLayout。取出这两个属性的值,测量父布局的宽高,乘百分比就是实际的宽高,然后确定在父控件中的位置。

三,自定义样式属性

在values文件夹中新建attrs.xml,内容如下:
layout_widthPercent和layout_heightPercent都是浮点型,0-1之间的值,代表百分百。

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="percentRelativeLayout">        <attr name="layout_widthPercent" format="float"></attr>        <attr name="layout_heightPercent" format="float"></attr>    </declare-styleable></resources>

四,自定义percentRelativeLayout

简单粗暴,根据xml布局中的子view的LayoutParams获取实际宽高。

public class PercentRelativeLayout extends RelativeLayout{    public PercentRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        // TODO Auto-generated constructor stub    }    public PercentRelativeLayout(Context context, AttributeSet attrs) {        super(context, attrs);        // TODO Auto-generated constructor stub    }    public PercentRelativeLayout(Context context) {        super(context);        // TODO Auto-generated constructor stub    }       @Override    public LayoutParams generateLayoutParams(AttributeSet attrs) {        // TODO Auto-generated method stub        return new LayoutParams(getContext(), attrs);    }    //测量自己    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        //获取自身的宽高        int widthHint = View.MeasureSpec.getSize(widthMeasureSpec);        int heightHint = View.MeasureSpec.getSize(heightMeasureSpec);        for(int i = 0;i<this.getChildCount();i++){            View child = this.getChildAt(i);            //获取孩子view的布局属性            ViewGroup.LayoutParams params = child.getLayoutParams();            float widthPercent = 0;            float heightPercent = 0;            //含有自定义的属性,则获取百分百            if(params instanceof PercentRelativeLayout.LayoutParams){                widthPercent = ((PercentRelativeLayout.LayoutParams) params).getWidthPercent();                heightPercent = ((PercentRelativeLayout.LayoutParams) params).getHeightPercent();            }            if(widthPercent == 0|| heightPercent == 0){                continue;//百分百为0,跳出此次循环            }            //真实的宽高            params.width = (int) (widthPercent*widthHint);            params.height = (int) (heightPercent*heightHint);        }        super.onMeasure(widthMeasureSpec, heightMeasureSpec);    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        // TODO Auto-generated method stub        super.onLayout(changed, l, t, r, b);    }    public static class LayoutParams extends RelativeLayout.LayoutParams{        private float widthPercent;        private float heightPercent;        public float getWidthPercent() {            return widthPercent;        }        public void setWidthPercent(float widthPercent) {            this.widthPercent = widthPercent;        }        public float getHeightPercent() {            return heightPercent;        }        public void setHeightPercent(float heightPercent) {            this.heightPercent = heightPercent;        }        //构造函数里面获取自定义样式属性的值        public LayoutParams(Context c, AttributeSet attrs) {            super(c, attrs);            TypedArray array = c.obtainStyledAttributes(attrs, R.styleable.percentRelativeLayout);            widthPercent = array.getFloat(R.styleable.percentRelativeLayout_layout_widthPercent, widthPercent);            heightPercent = array.getFloat(R.styleable.percentRelativeLayout_layout_heightPercent,heightPercent);            array.recycle();        }        public LayoutParams(int w, int h) {            super(w, h);            // TODO Auto-generated constructor stub        }        public LayoutParams(android.view.ViewGroup.LayoutParams source) {            super(source);            // TODO Auto-generated constructor stub        }        public LayoutParams(MarginLayoutParams source) {            super(source);            // TODO Auto-generated constructor stub        }    }}

五,布局中引用自定义View和属性

上菜了。不用 系统控件,用咱们自己的。

<com.example.view.PercentRelativeLayout     xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res/com.example.percent_relativelayout_dn"    android:layout_width="match_parent"    android:layout_height="match_parent">    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="测试百分比布局"         android:layout_centerInParent="true"        app:layout_widthPercent = "0.5"        app:layout_heightPercent = "0.5"        android:background="#00ff00"        android:id="@+id/textview"        /></com.example.view.PercentRelativeLayout>

六,实现与总结

直接在activity中运行测试,是不是很完美了。宽高半分比布局OK了。

public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }}

五大布局都可以实现,今天只是分享了RelativieLayout的中控件的百分百自适应。之前在github上面看了一个很全面的百分百布局方案,其实原理就这样。
欢迎交流,杜乾,Dusan,Q 291902259。

0 0
原创粉丝点击