接着上一篇:Android屏幕适配 - 百分比(一)
既然我们能通过更改pt这个系统单位做到,拿为什么我们不能直接修改dp呢?
方案二:直接替换系统单位dp
上一篇我们有具体分析,只要修改这个方法的pt转化就可以做到全局适配,同样修改这个方法里面的dp也能做的。
我们看到value * metrics.density,所以如果直接修改dp我们需要hook掉的其实是density。
这个理论上看是ok的,dp转换到px就是由density的值决定的。
那么density的这个值是从哪里获取过来的呢? 会不会有时机会修改掉这个值呢?hook掉这个的时机是什么呢?
默认的density取自于系统文件 qemu.sf.lcd_density 或 ro.sf.lcd_density 中。
通过adb shell getprop ro.sf.lcd_density 命令,我能获取到手机的density值
默认的density是这么获取到的。
那会不会有时机会修改掉这个值呢?
是的,有,在7.0系统以上手机支持了 屏幕缩放可以调整的功能。
以华为P9 plus为例,我们把显示模式调整为中,这时候我们写demo,在activity的onCreate的时机获取的density值
这里的densityDpi对应的是我们上面说的设备的density,可以看到从480变成了440.
我们发现density会随着屏幕缩放大小调节变化。
细心的朋友会发现我们上面的打印了两种获取density的方式,getResource和Window。
我们具体说明下:
获取density的两种方式:
1. WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
2. DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
两种方式的区别:
在双屏显示的时候调整屏幕大小时,第一种方式密度值是不实时生效的,所以我们舍弃第一种获取density的方式。
在双屏模式下,屏幕缩放调大后,我们看到application中的window的获取density的方式的值是没有实时生效变化的。
所以舍弃这种获取方式。
看到调节系统屏幕大小时候density会变化,我们hook掉density的时机就要在这个之后。
详细见官网地址:https://developer.android.com/about/versions/nougat/android-7.0-changes.html
既然是按照运行时更改处理,是不是可以理解为一定会走到这个生命周期
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.d("MyApplication", "onConfigurationChanged");
}
我们demo实际验证下:
实际检验,在调节屏幕大小和字体大小的时候都会回调到,那是不是说,我们只要在Application的onCreate中和onConfigurationChanged中修改resource方式的density的值就可以做到全局适配呢?
我们惊喜的发现是的,能够做到全局适配,那是不是这样就能做到屏幕百分比适配,还最大限度解决了业务成本。
哈哈哈~有没有很惊喜~