我們先來復(fù)習(xí)一下店dp、dpi、px
- dp(density-independent pixel )設(shè)備獨(dú)立像素值,根據(jù)系統(tǒng)轉(zhuǎn)換成px
- dpi(dots per inch) 每英寸包含的像素點(diǎn)
- px 像素點(diǎn),假如我們的手機(jī)分辨率是7201280,手機(jī)橫向有720個(gè)像素點(diǎn)(720px),縱向1280個(gè)點(diǎn)(1280px)
20190709142158952.png
如圖,假如手機(jī)分辨率7201280,5英寸,勾股定理求出對(duì)角線的像素點(diǎn),然后除以5,就是dpi=294.
在Android中,160dpi中,1dp=1px(一個(gè)基準(zhǔn)),我們這個(gè)294dpi,此時(shí)1dp=1.8px,
UI出圖7201280,5英寸,設(shè)計(jì)圖中有一個(gè)button要占屏幕一半,在720的上是360px,換算成dp是200dp。那如果我們?cè)?0801920 5.5英寸下,設(shè)置同樣的200dp呢?在此分辨率下dpi=400,1dp=2.5px,那么200dp對(duì)應(yīng)的是500px,不是屏幕的一半微信圖片_20200318103705.png
此時(shí)問題就在2.5這個(gè)數(shù)上,那如果想要屏幕的一半,2.5應(yīng)該換成2.7
1080/400 不是正好是2.7嗎,1080是我們當(dāng)前分辨率的水平像素,400從哪里來的呢?400就是設(shè)計(jì)圖寬度400dp
現(xiàn)在來看看2.5和2.7的關(guān)系?
2.5是用常規(guī)方式求出來的,也就是說1080*1920分辨率下,系統(tǒng)的默認(rèn)的就是2.5,我們需要把密度2.5換成2.7,這不就解決適配了嗎
public class Density {
private static final float WIDTH =400;//參考設(shè)備的寬,理解成設(shè)計(jì)圖
private static float appDensity;//表示屏幕密度
private static float appScaleDensity; //字體縮放比例,默認(rèn)appDensity
public static void setDensity(final Application application, Activity activity){
//獲取當(dāng)前app的屏幕顯示信息
DisplayMetrics displayMetrics = application.getResources().getDisplayMetrics();
if (appDensity == 0){
//初始化賦值操作
appDensity = displayMetrics.density;
appScaleDensity = displayMetrics.scaledDensity;
//添加字體變化監(jiān)聽回調(diào)
application.registerComponentCallbacks(new ComponentCallbacks() {
@Override
public void onConfigurationChanged(Configuration newConfig) {
//字體發(fā)生更改,重新對(duì)scaleDensity進(jìn)行賦值
if (newConfig != null && newConfig.fontScale > 0){
appScaleDensity = application.getResources().getDisplayMetrics().scaledDensity;
}
}
@Override
public void onLowMemory() {
}
});
}
//計(jì)算目標(biāo)值density, scaleDensity, densityDpi
float targetDensity = displayMetrics.widthPixels / WIDTH; // 720/ 400 = 1.8
float targetScaleDensity = targetDensity * (appScaleDensity / appDensity);
int targetDensityDpi = (int) (targetDensity * 160); 基準(zhǔn)是160 1dp=1px
//替換Activity的density, scaleDensity, densityDpi
DisplayMetrics dm = activity.getResources().getDisplayMetrics();
dm.density = targetDensity;
dm.scaledDensity = targetScaleDensity;
dm.densityDpi = targetDensityDpi;
}
}
public class MainActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Density.setDensity(getApplication(), this);
setContentView(R.layout.activity_main);
}
}

