標(biāo)準(zhǔn):1920px * 1080 5英寸 480 3
三星s10-22801080 6.1英寸 414 2.58
MI mix2-19201080 5.99 368 2.29
android中的dp在渲染前會(huì)將dp轉(zhuǎn)為px,計(jì)算公式:
px = density * dp;
density = dpi / 160;
px = dp * (dpi / 160);

大致需求如下:
支持以寬或者高一個(gè)維度去適配,保持該維度上和設(shè)計(jì)圖一致;
支持dp和sp單位,控制遷移成本到最小。
density 是 DisplayMetrics 中的成員變量
DisplayMetrics#density 就是上述的density
DisplayMetrics#densityDpi 就是上述的dpi
DisplayMetrics#scaledDensity 字體的縮放因子,正常情況下和density相等,但是調(diào)節(jié)系統(tǒng)字體大小后會(huì)改變這個(gè)值
所有的dp和px的轉(zhuǎn)換都是通過 DisplayMetrics 中相關(guān)的值來計(jì)算的
以1920px * 1080px來設(shè)計(jì),以density為3來標(biāo)注,也就是屏幕其實(shí)是640dp * 360dp
假設(shè)設(shè)計(jì)圖寬度是360dp,以寬維度來適配。
那么適配后的 density = 設(shè)備真實(shí)寬(單位px) / 360,接下來只需要把我們計(jì)算好的 density 在系統(tǒng)中修改下即可,代碼實(shí)現(xiàn)如下:
在Activity#onCreate中調(diào)用
/**
* 屏幕適配
* 設(shè)計(jì)圖寬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;
}