一种屏幕适配方案

头条推出的修改DisplayMetrics的缩放级别的方案,侵入性极低,但是这要求所有的UI图按照同一套设计尺寸来进行布局,在这种情况下,如果你的项目里面有第三方控件,而恰好这些第三方控件的设计尺寸跟你的UI设计尺寸不一致,那头条的这个方案就不适用了,而且这种情况挺常见的,我这里提供的这种方案,侵入性就会比较高了,但是可以有效的避免上述问题,而且经过线上版本的几个迭代,一切正常,没出现过问题,下面上代码

import android.content.Context;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

/**
* 时间:2019/7/26 11:57
* 创建:菜籽
* 描述:
*/

public class SizeUtil {

    private static SizeUtil mSizeUtil;
    private float mDesignWith = 1080f;      // 设计图中的默认宽度
    private float mScaleGrade = 1f;         // 缩放等级

    public static SizeUtil getInstance(Context context) {
        if (mSizeUtil == null) {
            synchronized (SizeUtil.class) {
                if (mSizeUtil == null) {
                    mSizeUtil = new SizeUtil(context);
                }
            }
        }
        return mSizeUtil;
    }

    public int resetValue(int value) {
        return (int) mScaleGrade * value;
    }

    public float resetValue(float value) {
        return mScaleGrade * value;
    }

    public void resetView(View view) {
        resetScaleView(view);
        if (view instanceof ViewGroup){
            ViewGroup group = (ViewGroup) view;
            for (int i = 0; i < group.getChildCount(); i++) {
                resetScaleView(group.getChildAt(i));
            }
        }
    }

    private SizeUtil(Context context) {
        initScaleGrade(context);
    }

    private void initScaleGrade(Context context) {
        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        int widthPixels = metrics.widthPixels;              // 获取实际的屏幕宽度
        int heightPixels = metrics.heightPixels;            // 获取实际的屏幕高度
        if (metrics.widthPixels > metrics.heightPixels) {    // 横向屏幕
            mScaleGrade = widthPixels / mDesignWith;
        } else {                                             // 纵向屏幕
            mScaleGrade = heightPixels / mDesignWith;
        }
    }

    // 最小值取 1
    private int resetParam(int param) {
        int v = Math.round(mScaleGrade * param);
        if (v > 1) return v;
        return 1;
    }

    private void resetScaleView(View view) {
        if (view == null || mScaleGrade == 1f) return;
        if (view instanceof TextView) {
            TextView textView = (TextView) view;
            float size = textView.getTextSize() * mScaleGrade;
            textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
        }
        ViewGroup.LayoutParams params = view.getLayoutParams();
        if (params == null) return;
        if (params.width > 0) {
            params.width = Math.round(mScaleGrade * params.width);
        }
        if (params.height > 0) {
            params.height = Math.round(mScaleGrade * params.height);
        }
        if (params instanceof ViewGroup.MarginLayoutParams) {
            ViewGroup.MarginLayoutParams marginParams = (ViewGroup.MarginLayoutParams) params;
            marginParams.leftMargin = resetParam(marginParams.leftMargin);
            marginParams.rightMargin = resetParam(marginParams.rightMargin);
            marginParams.topMargin = resetParam(marginParams.topMargin);
            marginParams.bottomMargin = resetParam(marginParams.bottomMargin);
        }
        view.setPadding(resetParam(view.getPaddingLeft()), resetParam(view.getPaddingTop()), resetParam(view.getPaddingRight()), resetParam(view.getPaddingBottom()));
        view.setMinimumWidth(resetParam(view.getMinimumWidth()));
        view.setMinimumHeight(resetParam(view.getMinimumHeight()));
        view.setLayoutParams(params);
    }
}

调用方式:在activity的setContentView()后,通过SizeUtil.resetView(View view)方法即可

对于需要手动add的view,在add前通过SizeUtil.resetView(View view)进行一次缩放

对于需要再代码中设置尺寸的view,需要在设置前调用SizeUtil.resetValue()方法对尺寸重新计算

你可能感兴趣的:(工具类,适配)