Android 屏幕适配方案

转发安卓适配方案
今日头条方案

适配原因

原生渲染前会将dp转为px,dpi就是导致差异化因素也叫像素密度,根据设备分辨率和尺寸计算得出,出厂时已经决定了
density = dpi / 160
px = dp * density
Android 屏幕适配方案_第1张图片

适配方案

1.dimens基于px适配(宽高限定符适配)

在res文件中,定义不同分辨率px参数,例如values-480*320 ,但是这种方案由于手机分辨率太多,局限性太高,弃用。

2.dimens基于dp适配(smallestWidth适配)

这种是根据最小宽度限定符,android会识别屏幕可用宽高的最小dp值,然后根据结果去寻找对应限定符的文件夹下的资源文件。
比如没有value-sw360dp 文件夹会向下寻找 value-sw350dp ,这种增加了分辨率匹配的容错率。
但是这种弊端是,会增加多个文件夹,而且也不能完美匹配所有机型

3.今日头条适配

今日头条适配方案是通过修改手机设备密度density完成的,通过修改density值,强行把所有不同尺寸分辨率的手机的宽度dp值改成一个统一的值,这样就解决了所有的适配问题。

这个方案缺点就是如果是三方库,也许没有进项适配,显示会有差异。老项目使用,由于实际尺寸变化,可能得重新出一套设计图

/**
     * 适配:修改设备密度
     */
    private static float sNoncompatDensity;
    private static float sNoncompatScaledDensity;
 
    public 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 targetScaleDensity = targetDensity * (sNoncompatScaledDensity / sNoncompatDensity);
        int targetDensityDpi = (int) (160 * targetDensity);
 
        appDisplayMetrics.density = targetDensity;
        appDisplayMetrics.scaledDensity = targetScaleDensity;
        appDisplayMetrics.densityDpi = targetDensityDpi;
 
        final DisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics();
        activityDisplayMetrics.density = targetDensity;
        activityDisplayMetrics.scaledDensity = targetScaleDensity;
        activityDisplayMetrics.densityDpi = targetDensityDpi;
 
    }

你可能感兴趣的:(Android)