Android屏幕适配之修改density

标准:1920px * 1080 5英寸 480 3
三星s10-22801080 6.1英寸 414 2.58
MI mix2-1920
1080 5.99 368 2.29

android中的dp在渲染前会将dp转为px,计算公式:
px = density * dp;
density = dpi / 160;
px = dp * (dpi / 160);

dpi计算

大致需求如下:
支持以宽或者高一个维度去适配,保持该维度上和设计图一致;
支持dp和sp单位,控制迁移成本到最小。

density 是 DisplayMetrics 中的成员变量
DisplayMetrics#density 就是上述的density
DisplayMetrics#densityDpi 就是上述的dpi
DisplayMetrics#scaledDensity 字体的缩放因子,正常情况下和density相等,但是调节系统字体大小后会改变这个值

所有的dp和px的转换都是通过 DisplayMetrics 中相关的值来计算的

以1920px * 1080px来设计,以density为3来标注,也就是屏幕其实是640dp * 360dp
假设设计图宽度是360dp,以宽维度来适配。

那么适配后的 density = 设备真实宽(单位px) / 360,接下来只需要把我们计算好的 density 在系统中修改下即可,代码实现如下:

在Activity#onCreate中调用

/**
     * 屏幕适配
     * 设计图宽360dp
     */
    private static float sNoncompatDensity;
    private static float sNoncompatScaledDensity;
    private static void setCustomDensity(@NonNull Activity activity, @NonNull final Application application) {
        DisplayMetrics appDisplayMetrics = application.getResources().getDisplayMetrics();
        if (sNoncompatDensity == 0) {
            sNoncompatDensity = appDisplayMetrics.density;
            sNoncompatScaledDensity = appDisplayMetrics.scaledDensity;
            application.registerComponentCallbacks(new ComponentCallbacks() {
                @Override
                public void onConfigurationChanged(Configuration newConfig) {
                    if (newConfig != null && newConfig.fontScale > 0) {
                        sNoncompatScaledDensity = application.getResources().getDisplayMetrics().scaledDensity;
                    }
                }

                @Override
                public void onLowMemory() {

                }
            });
        }
        float targetDensity = appDisplayMetrics.widthPixels / 360;
        float targetScaledDensity = targetDensity * (sNoncompatScaledDensity / sNoncompatDensity);
        int targetDensityDpi = (int) (160 * targetDensity);

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

        DisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics();
        activityDisplayMetrics.density = targetDensity;
        activityDisplayMetrics.scaledDensity = targetScaledDensity;
        activityDisplayMetrics.densityDpi = targetDensityDpi;
    }

你可能感兴趣的:(Android屏幕适配之修改density)