学习笔记:屏幕适配方案(百分比适配)

251 阅读1分钟

思路:通过自定义ViewGroup,在onMeasure中,根据xml中设置的百分比重新设置子View的宽高

撸码

代码逻辑相对简单,记录一下一种适配思想

1.定义相关属性

<resources>
<declare-styleable name="LinearLayout">
    <attr name="percent_width" format="float" />
    <attr name="percent_height" format="float" />
    <attr name="percent_left_margin" format="float" />
    <attr name="percent_right_margin" format="float" />
    <attr name="percent_top_margin" format="float" />
    <attr name="percent_bottom_margin" format="float" />
</declare-styleable>

2.重写LinearLayout

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.Nullable;

public class LinearLayout extends android.widget.LinearLayout {


    public LinearLayout(Context context) {
        super(context);
    }

    public LinearLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public LinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    /**
     * 将AttributeSet封装成LayoutParams
     */
    static class LayoutParams extends android.widget.LinearLayout.LayoutParams {

        //宽高百分比
        private float percentWidth;
        private float percentHeight;
        //水平方向margin百分比
        private float percentLeftMargin;
        private float percentRightMargin;
        //垂直方向margin百分比
        private float percentTopMargin;
        private float percentBottomMargin;

        LayoutParams(Context c, AttributeSet attrs) {
            super(c, attrs);
            TypedArray array = c.obtainStyledAttributes(attrs, R.styleable.LinearLayout);
            //获取相关属性
            percentWidth = array.getFloat(R.styleable.LinearLayout_percent_width, 0);
            percentHeight = array.getFloat(R.styleable.LinearLayout_percent_height, 0);
            percentLeftMargin = array.getFloat(R.styleable.LinearLayout_percent_left_margin, 0);
            percentRightMargin = array.getFloat(R.styleable.LinearLayout_percent_right_margin, 0);
            percentTopMargin = array.getFloat(R.styleable.LinearLayout_percent_top_margin, 0);
            percentBottomMargin = array.getFloat(R.styleable.LinearLayout_percent_bottom_margin, 0);
            array.recycle();
        }
    }

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //得到当前父控件的宽高
        float width = MeasureSpec.getSize(widthMeasureSpec);
        float height = MeasureSpec.getSize(heightMeasureSpec);
        //循环遍历所有子控件
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            View child = getChildAt(i);
            ViewGroup.LayoutParams layoutParams = child.getLayoutParams();
            //如果子控件的LayoutParams是属于该ViewGroup的LayoutParams
            if (layoutParams instanceof LayoutParams) {
                float percentWidth = ((LayoutParams) layoutParams).percentWidth;
                float percentHeight = ((LayoutParams) layoutParams).percentHeight;

                float percentLeftMargin = ((LayoutParams) layoutParams).percentLeftMargin;
                float percentRightMargin = ((LayoutParams) layoutParams).percentRightMargin;

                float percentTopMargin = ((LayoutParams) layoutParams).percentTopMargin;
                float percentBottomMargin = ((LayoutParams) layoutParams).percentBottomMargin;
                // 如果百分比为0则不处理相关的计算
                if (percentWidth > 0) {
                    layoutParams.width = (int) (width * percentWidth);
                }
                if (percentHeight > 0) {
                    layoutParams.height = (int) (height * percentHeight);
                }
                if (percentLeftMargin > 0) {
                    ((LayoutParams) layoutParams).leftMargin = (int) (width * percentLeftMargin);
                }
                if (percentRightMargin > 0) {
                    ((LayoutParams) layoutParams).rightMargin = (int) (width * percentRightMargin);
                }
                if (percentTopMargin > 0) {
                    ((LayoutParams) layoutParams).topMargin = (int) (height * percentTopMargin);
                }
                if (percentBottomMargin > 0) {
                    ((LayoutParams) layoutParams).bottomMargin = (int) (width * percentBottomMargin);
                }
            }

        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}