解决Bitmap图片不同真机显示效果不一致问题
问题
最近开发过程中遇到个很奇怪的问题,就是在做滑动验证模块的时候(参考的这里,自己改了改),在bitmap上操作底部图层和滑块图层大小不一致的问题。
很奇怪啊,在大部分手机上是没问题的,在全面屏手机上必定出现,后面我用华为手机更改系统显示效果(文字设置里面,非文字大小,部分安卓手机可能没有)后,这样的情况也必定出现。
经过一番思考,我觉得应该是我写的屏幕适配出了问题。
屏幕适配
先看下屏幕适配,这里参考的是字节跳动的屏幕适配方案,这里还有个别人写好的工具类,感觉还不错!
// 系统的Density
private static float sNoncompatDensity;
// 系统的ScaledDensity
private static float sNoncompatScaledDensity;
public static void setCustomDensity(Activity activity, Application application) {
DisplayMetrics displayMetrics = application.getResources().getDisplayMetrics();
if (sNoncompatDensity == 0) {
sNoncompatDensity = displayMetrics.density;
sNoncompatScaledDensity = displayMetrics.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() {
}
});
}
// 此处以360dp的设计图作为例子
float targetDensity=displayMetrics.widthPixels/360;
float targetScaledDensity=targetDensity*(sNoncompatScaledDensity/sNoncompatDensity);
int targetDensityDpi= (int) (160 * targetDensity);
displayMetrics.density = targetDensity;
displayMetrics.scaledDensity = targetScaledDensity;
displayMetrics.densityDpi = targetDensityDpi;
DisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics();
activityDisplayMetrics.density = targetDensity;
activityDisplayMetrics.scaledDensity = targetScaledDensity;
activityDisplayMetrics.densityDpi = targetDensityDpi;
}
这里有个问题啊,如果在登录activity中用了这样的适配,那后面的activity也会受影响,问题来了,如果后面的activity需要退出软件,例如使用exit(0),这里将无法直接退出,会回到入口activity,并且适配出问题。
解决办法是在需要直接退出软件的地方,重新设置一次屏幕适配,这样就没问题了!
解决思路
在字节适配方案中,最核心的就是更改当前activity的适配,我就打印了系统的density和图片的density,果然就发现了问题,两者的density不一致了。
- 系统density
int density = getContext().getResources().getDisplayMetrics().densityDpi
- Bitmap的density
int density = mBitmap.getDensity()
解决办法
理清楚问题所在后,就好解决了,统一density不就完事了。
在 onDraw(Canvas canvas) 方法中,根据mBitmap的density,修改canvas的density,调试发现可以了。
if (null != mBitmap) {
canvas.setDensity(mBitmap.getDensity());
//TODO 绘制其他形状
}
完美撒花