首先,先了解一下幾個基本概念:
px:像素點;
dpi:像素密度,每英寸有多少個像素點;對應于DisplayMetrics類中屬性densityDpi的值;
dp:可以根據不同的屏幕獲得不同的像素數量;當屏幕每英寸有160個像素時,dp與px等價;dp最終都要化為像素數量來衡量大小的,因為只有像素數量最直觀;
density:密度(以mdpi(160dpi)為基準,相對標準情況下的像素密度的比例);
density = dpi / 160;
density = px / dp;
通常情況下,一部手機的分辨率是寬x高,屏幕大小是以寸為單位,那么三者的關系是:

屏幕dpi.jpg
Android開發(fā)中,圖片素材會根據素材的分辨率大小,放在如下幾個文件夾中:
ldpi(120dpi)
mdpi(160dpi)
hdpi(240dpi)
xdpi(320dpi)
xxdpi(480dpi)
xxxdpi(640dpi)
以mdpi(160dpi)為基準,比例關系:0.75:1:1.5:2:3:4。
上述文件夾不是指定具體的分辨率,而是一個范圍,如ldpi(value<120dpi),mdpi(120dpi<value<160dpi),以此類推。資源文件加載時,就是根據手機分辨率選擇合適的文件夾加載資源。
UI設計圖是按屏幕寬度為360dp來設計的,如果需要修改,只能改density。
今日頭條的這種適配,只需要在baseActivity中添加一句話即可。
/**
* 適配:修改設備密度
*/
private static float sNoncompatDensity;
private static float sNoncompatScaledDensity;
public static void setCustomDensity(Activity activity) {
final Application application = BaseApplication.getInstance();
DisplayMetrics appDisplayMetrics = application.getResources().getDisplayMetrics();
if (sNoncompatDensity == 0) {
sNoncompatDensity = appDisplayMetrics.density;
sNoncompatScaledDensity = appDisplayMetrics.scaledDensity;
// 防止系統(tǒng)切換后不起作用
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;
DisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics();
activityDisplayMetrics.density = targetDensity;
activityDisplayMetrics.scaledDensity = targetScaleDensity;
activityDisplayMetrics.densityDpi = targetDensityDpi;
}