首先我们要知道关于屏幕适配相关基础知识 ,

概念来源https://developer.android.google.cn/guide/practices/screens_support

今天头条原文:https://mp.weixin.qq.com/s/d9QCoBP6kV9VSWvVldVVwA

术语和概念
屏幕尺寸
按屏幕对角测量的实际物理尺寸。
为简便起见,Android 将所有实际屏幕尺寸分组为四种通用尺寸:小、 正常、大和超大。

屏幕密度 dpi
屏幕物理区域中的像素量;通常称为 dpi(每英寸 点数)。例如, 与“正常”或“高”密度屏幕相比,“低”密度屏幕在给定物理区域的像素较少。
为简便起见,Android 将所有屏幕密度分组为六种通用密度: 低、中、高、超高、超超高和超超超高。

方向
从用户视角看屏幕的方向,即横屏还是 竖屏,分别表示屏幕的纵横比是宽还是高。请注意, 不仅不同的设备默认以不同的方向操作,而且 方向在运行时可随着用户旋转设备而改变。

分辨率
屏幕上物理像素的总数。添加对多种屏幕的支持时, 应用不会直接使用分辨率;而只应关注通用尺寸和密度组指定的屏幕 尺寸及密度。

密度无关像素 (dp)
在定义 UI 布局时应使用的虚拟像素单位,用于以密度无关方式表示布局维度 或位置。
密度无关像素等于 160 dpi 屏幕上的一个物理像素,这是 系统为“中”密度屏幕假设的基线密度。在运行时,系统 根据使用中屏幕的实际密度按需要以透明方式处理 dp 单位的任何缩放 。dp 单位转换为屏幕像素很简单: px = dp * (dpi / 160)。 例如,在 240 dpi 屏幕上,1 dp 等于 1.5 物理像素。在定义应用的 UI 时应始终使用 dp 单位 ,以确保在不同密度的屏幕上正常显示 UI。

dp和px的转换方程式

px = dp * (dpi / 160)

工具类

/**
 * Created by WangKunKun on 2018/8/30
 * 注解:根据今日头条公布的适配方法完善的方法
 * px = dp * (dpi / 160)
 **/
public class AutoUtils {

public static float commonScaleDensity;
private static int targetWidth;
private static int targetHeight;
private static float size;
private static int targetDpi;

/**
 * 初始化 工具类 只需要初始化一次就可以了
 * @param targetWidth 适配模板的宽(px)
 * @param targetHeight 适配模板的高(px)
 * @param size 适配模板的尺寸(英寸),手机的对角线
 */
public static void init(@NonNull int targetWidth,@NonNull int targetHeight,@NonNull float size){
    AutoUtils.targetWidth = targetWidth;
    AutoUtils.targetHeight = targetHeight;
    AutoUtils.size = size;
    //计算模板的dpi
    targetDpi = (int) (Math.sqrt(targetHeight^2+targetWidth^2)/size);
}

private static void setAutoDestentry(@NonNull Activity activity, final Application application,boolean isWidth) {
    if (targetDpi==0){
        throw new NullPointerException("你还没设置适配的模板,目标模板不能为空,请先初始化init方法");
    }
    DisplayMetrics appDisplayMetrics = application.getResources().getDisplayMetrics();
    if (commonScaleDensity == 0) {
        commonScaleDensity = appDisplayMetrics.scaledDensity;
        application.registerComponentCallbacks(new ComponentCallbacks() {
            @Override
            public void onConfigurationChanged(Configuration configuration) {
                if (configuration != null && configuration.fontScale > 0) {
                    commonScaleDensity = application.getResources().getDisplayMetrics().scaledDensity;
                }
            }
            @Override
            public void onLowMemory() {

            }
        });
    }
    float targetDensity;
    if (isWidth){
        targetDensity = (targetDpi/160)*appDisplayMetrics.widthPixels/targetWidth;
    }else {
        targetDensity = (targetDpi/160)*appDisplayMetrics.heightPixels/targetHeight;
    }
    int targetDensityDip = (int) (targetDensity * 160);
    float targetScaledDensity =targetDensity* commonScaleDensity / appDisplayMetrics.density;

    appDisplayMetrics.density = targetDensity;
    appDisplayMetrics.densityDpi = targetDensityDip;
    appDisplayMetrics.scaledDensity =targetScaledDensity;

    DisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics();
    appDisplayMetrics.scaledDensity = targetScaledDensity;
    activityDisplayMetrics.density = targetDensity;
    activityDisplayMetrics.densityDpi = targetDensityDip;

}

/**
 *以模板的高为标准适配
 * @param activity
 * @param application
 */
public static void setAutoDensityByHeight(Activity activity,Application application){
    setAutoDestentry(activity,application,false);
}

/**
 * 以模板的宽为标准适配
 * @param activity
 * @param application
 */
public static void setAutoDensityByWidth(Activity activity,Application application){
    setAutoDestentry(activity,application,true);
}

}

使用方式

在初始化一次init()方法 之后再每一个使用的actvity或者是fragment中 调用setAutoDensityByWidth() 或者setAutoDensityByHeight()方法 注意每个activity中调用以最后一次为准
例如我们公司的模板是1334*750 4.7英寸 所以
AutoUtils.init(1337,750,4.7);
AutoUtils.setAutoDensityByWidth(this,getApplication());//