学习自
https://zhuanlan.zhihu.com/p/37199709
机型适配目前暂时我认为分两块:1.尺寸2.代码(不同系统引发的莫名其妙的crash)
本文简单介绍尺寸
dp、px的换算
dp*dpi/160=px(dpi/160也就是density)
举个例子:屏幕分辨率为:1920*1080,屏幕尺寸为5吋的话,那么dpi为440。
但是UI给的图一般都是按360dp来的
然而我们这里计算出来的宽度1080/(440/160)显然不等于360dp
这就是机型适配的问题
所以一种为大多数人认可的方案就是适配宽度。
然后仅仅宽度上可以适配成360dp
高度就不考虑了
DisplayMetrics 实例通过 Resources#getDisplayMetrics 可以获得
Resouces通过Activity或者Application的Context获得
DisplayMetrics 实例中有:
1.DisplayMetrics#density 就是上述的density
2.DisplayMetrics#densityDpi 就是上述的dpi
3.DisplayMetrics#scaledDensity 字体的缩放因子,正常情况下和density相等,但是调节系统字体大小后会改变这个值
最终解决
density = 设备真实宽(单位px) / 360
这个是我们希望实现的density
public static void setCustomDensity(Activity activity, Application application) { final DisplayMetrics appDisplayMetrics = application.getResources().getDisplayMetrics(); final float targetDensity = appDisplayMetrics.widthPixels / 360; final int targetDensityDpi = (int) (160 * targetDensity); appDisplayMetrics.density = appDisplayMetrics.scaledDensity = targetDensity; appDisplayMetrics.densityDpi = targetDensityDpi; final DisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics(); activityDisplayMetrics.density = activityDisplayMetrics.scaledDensity = targetDensity; activityDisplayMetrics.densityDpi = targetDensityDpi; }
上面代码的宽度适配很成功了,但是字体适配不行,所以增加字体适配后的如下
private static float sNoncompatDensity; private static float sNoncompatScaledDensity; public static void setCustomDensity(Activity activity, Application application) { final DisplayMetrics appDisplayMetrics = application.getResources().getDisplayMetrics(); if (sNoncompatDensity == 0) { sNoncompatDensity = appDisplayMetrics.density; sNoncompatScaledDensity = appDisplayMetrics.scaledDensity; application.registerComponentCallbacks(new ComponentCallbacks() { @Override public void onConfigurationChanged(Configuration newConfig) { if (newConfig != null && newConfig.fontScale > 0) sNoncompatScaledDensity = application.getResources().getDisplayMetrics().scaledDensity; } @Override public void onLowMemory() { } }); } final float targetDensity = appDisplayMetrics.widthPixels / 360; final float targetScaleDensity = targetDensity * (sNoncompatScaledDensity / sNoncompatDensity); final int targetDensityDpi = (int) (160 * targetDensity); appDisplayMetrics.density = targetDensity; appDisplayMetrics.scaledDensity = targetScaleDensity; appDisplayMetrics.densityDpi = targetDensityDpi; final DisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics(); activityDisplayMetrics.density = targetDensity; activityDisplayMetrics.scaledDensity = targetScaleDensity; activityDisplayMetrics.densityDpi = targetDensityDpi; }
代码很简单,就不解释了,掌握了这个就算入个门了,也能简单地解决一些尺寸适配的问题了。
另外推荐一个不错的实现:
https://www.jianshu.com/p/b6b9bd1fba4d
有500+start了,看起来挺靠谱的!