1.为什么会出现屏幕不适配的问题
Android的画面编码,控件的宽高等属性通常使用的单位都是dp
举个例子:屏幕分辨率为:1920*1080,屏幕尺寸为5寸的话,那么dpi为440。
假设我们UI设计图是按屏幕宽度为360dp来设计的,那么在上述设备上,屏幕宽度其实为1080/(440/160)=392.7dp,也就是屏幕是比设计图要宽的。这种情况下, 即使使用dp也是无法在不同设备上显示为同样效果的。 同时还存在部分设备屏幕宽度不足360dp,这时就会导致按360dp宽度来开发实际显示不全的情况。
而且上述屏幕尺寸、分辨率和像素密度的关系,很多设备并没有按此规则来实现, 因此dpi的值非常乱,没有规律可循,从而导致使用dp适配效果差强人意。
然而屏幕适配一般都是统一不同机型的宽度或者高度,因为现在手机在屏幕高度上参差不齐,所以常见的屏幕适配方案都是针对宽度是适配。
2.解决方案
BaseActivity的onCreate方法中调用setCustomDensity(),即可达成全局适配
private var aNoncompatDensity =0f
private var aNoncompatScaledDensity =0f
private fun setCustomDensity(application: Application, activity: Activity) {
val appDisplayMetrics: DisplayMetrics = application.getResources().getDisplayMetrics()
if (aNoncompatDensity ==0f) {
aNoncompatDensity = appDisplayMetrics.density
aNoncompatScaledDensity = appDisplayMetrics.scaledDensity
application.registerComponentCallbacks(object : ComponentCallbacks {
override fun onConfigurationChanged(@NonNull newConfig: Configuration) {
if (newConfig.fontScale >0) {
aNoncompatScaledDensity = application.getResources().getDisplayMetrics().scaledDensity
}
}
override fun onLowMemory() {}
})
}
val targetDensity = (appDisplayMetrics.widthPixels /360).toFloat()
val targetScaledDensity = targetDensity * (aNoncompatScaledDensity /aNoncompatDensity)
val targetDensityDpi = (targetDensity *160).toInt()
//设置application的Density
appDisplayMetrics.density = targetDensity
appDisplayMetrics.scaledDensity = targetScaledDensity
appDisplayMetrics.densityDpi = targetDensityDpi
//设置activity的Density
val activityDisplayMetrics = activity.resources.displayMetrics
activityDisplayMetrics.density = targetDensity
activityDisplayMetrics.scaledDensity = targetScaledDensity
activityDisplayMetrics.densityDpi = targetDensityDpi
}
网友评论