修改系统修改系统density、、densityDpi适配适配
文章目录文章目录一、简述二、追根溯源三、实现3.1 定义Density用于对系统类值的修改3.2 在MainActivity中调用3.3 处理应用程序关
于字体大小的监听3.4 如果多界面统一处理怎么办?3.4.1 BaseActivity3.4.2 监听应用程序的变化四、完整代码
一、简述一、简述
修改density(屏幕密度,若每英寸有160像素点,该值就为1)、scaleDensity(字体缩放比例),densityDpi(屏幕上每英寸
有多少像素点,如160)的值,就是修改系统内部对于目标尺寸而言的像素密度。
二、追根溯源二、追根溯源
每个控件的显示,dp、sp等最终都会转换成px为单位,原因在于android源码TypedValue#applyDimension:
public static float applyDimension(int unit, float value,
DisplayMetrics metrics)
{
switch (unit) {
case COMPLEX_UNIT_PX:
return value;
case COMPLEX_UNIT_DIP:
return value * metrics.density;
case COMPLEX_UNIT_SP:
return value * metrics.scaledDensity;
case COMPLEX_UNIT_PT:
return value * metrics.xdpi * (1.0f/72);
case COMPLEX_UNIT_IN:
return value * metrics.xdpi;
case COMPLEX_UNIT_MM:
return value * metrics.xdpi * (1.0f/25.4f);
}
return 0;
}
传入的参数分别是:单位、值、屏幕显示的DisplayMetrics 对象。通过上面的源码可以看出,不管传入的是什么单位,最终都
会被转换成px。所以,如果要修改控件的尺寸,只需要修改如果要修改控件的尺寸,只需要修改metrics.density或或metrics.scaledDensity即可即可。修改density和
自定义view适配中的scaleX、scaleY类似,不同的设备下的density也不同,同一个分辨率下的density也有可能不一样。所以
要对density进行调整,使其跟随分辨率来进行变换。
假设目标设备的像素密度为160,运行设备的像素密度为320,这样算出来的dp值就是320/160=2。既然要修改,就要给出参
考像素密度。
三、实现三、实现
3.1 定义定义Density用于对系统类值的修改用于对系统类值的修改
定义静态方法setDensity,需要传入application和activity。获取当前app的屏幕显示信息:
DisplayMetrics displayMetrics = application.getResources().getDisplayMetrics();
定义成员变量表示屏幕密度、字体缩放比例:
private static float appDensity;//表示屏幕密度
private static float appScaleDensity; //字体缩放比例,默认appDensity
if判断赋值:
appDensity = displayMetrics.density;
appScaleDensity = displayMetrics.scaledDensity;
随后计算目标值density, scaleDensity, densityDpi:
float targetDensity = displayMetrics.widthPixels / WIDTH; //比如 1080 / 360 = 3.0
float targetScaleDensity = targetDensity * (appScaleDensity / appDensity);
int targetDensityDpi = (int) (targetDensity * 160);
替换Activity的density, scaleDensity, densityDpi:
DisplayMetrics dm = activity.getResources().getDisplayMetrics();
dm.density = targetDensity;
dm.scaledDensity = targetScaleDensity;
dm.densityDpi = targetDensityDpi;
3.2 在在MainActivity中调用中调用
必须在setContentView方法前调用:Density.setDensity(getApplication(),this);这样,参考设备(UI设计图)的宽为320dp,在
xml中写160dp就表示显示为宽度的一半,并且在任何设备上都会显示为屏幕的一半。
评论10