Android屏幕適配之–通過修改系統的屏幕像素比來實現屏幕的適配效果
關於Android中dip,dpi,density,px的詳細解釋參考簡書前輩的文章Android開發中dip,dpi,density,px等詳解
當然在下面的代碼中,density
代表的是縮放比,densityDpi
代表的是像素密度(就是一個dp
中有多少個px
),Android官方中是以160
爲基準dpi
做一個簡要的說明:在顯示中,實際都是以像素px爲單位來對控件的大小進行指定的,所以數值在換算的公式是這樣的
實際顯示的像素值px = 縮放比 * 設置的dp值
縮放比 = 實際的dpi / 160(基準dpi)
代碼不多,先直接把整個類的代碼貼上來吧
public class DensityUtil {
//屏幕的參考寬度值,單位是dp
private static float STAND_WIDTH = 320;
//系統原來的像素縮放比
private static float appDensity;
private static float appScaleDensity; //字體縮放比
public static void setDensity(final Application application, Activity activity) {
final DisplayMetrics appMetrics = application.getResources().getDisplayMetrics();
if (appDensity == 0) {
//獲取系統本來的像素縮放比和字體縮放比
appDensity = appMetrics.density;
appScaleDensity = appMetrics.scaledDensity;
}
application.registerComponentCallbacks(new ComponentCallbacks() {
@Override
public void onConfigurationChanged(Configuration newConfig) {
//代表字體大小進行了更改,需要對字體縮放比進行重新賦值
if(newConfig != null && newConfig.fontScale > 0){
appScaleDensity = application.getResources().getDisplayMetrics().scaledDensity;
}
}
@Override
public void onLowMemory() {
}
});
//通過實際的屏幕大小來計算新的屏幕像素縮放比
float targetDensity = appMetrics.widthPixels / STAND_WIDTH;
float targetScaleDensity = targetDensity * (appScaleDensity / appDensity);
float targetDensityDpi = targetDensity * 160;
//將獲取到的新的縮放比設置回去
DisplayMetrics actMetrics = activity.getResources().getDisplayMetrics();
actMetrics.density = targetDensity;
actMetrics.densityDpi = (int) targetDensityDpi;
actMetrics.scaledDensity = targetScaleDensity;
}
}
在調用的時候,要在目標界面Activity的setContentView代碼之前進行調用
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DensityUtil.setDensity(getApplication(),this);
setContentView(R.layout.activity_density);
}
整個思路就是先拿到整個屏幕的像素值,然後除以參照的設計圖中的設備寬度dp值,這樣就可以得到一個目標的縮放比,通過這個縮放比就可以得到字體的縮放比和像素密度,然後在把得到的這幾個值給設置回去。
疑問
可能在代碼中會有這樣的疑問,爲什麼要先獲取Application的appDensity、appScaleDensity這些參數,經過換算後替換成Activity的Density、ScaleDensity,而不是一開始直接獲取Activity的DisplayMetrics,然後從這個DisplayMetrics中提取Density、ScaleDensity等屬性,然後直接修改呢?
解答
是這樣的,當你改了一個Activity後,整個app所有的界面都會發生變化,比如A activity的density修改後就,bActivity的也相應發生修改,但是application的density並沒有變化,如果還需要再縮放那就是在已經縮放一次的基礎上還會再乘上一個對應的倍數,所有這裏使用app的DisplayMetrics主要是爲了確保計算正確