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主要是为了确保计算正确