We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
[TOC]
这篇文章讲解 Android 不同屏幕的适配方式
android 中的各种各种单位渲染之前都会转为 px。
上面的 dpi 根据屏幕真实的分辨率和尺寸来计算,每个设备都不一样。
一般情况下,手机的分辨率是宽* 高,屏幕大小以 寸 为单位,关系如下:dpi * 屏幕密度 = 宽^2 + 高^2
比如:手机屏幕分辨率为 1920 * 1080, 屏幕尺寸为5寸的话, dpi = 440.
如上,加入设计图以 360dp 来设计。上面的屏幕实际为 1080/(440/160)= 392.7dp。
这种情况下, 即使用 dp 也无法做到在不同屏幕下可以显示同样的效果。同时还存在部分屏幕不足 360dp,显示不全的情况。
一般我们设计图都是以固定的尺寸来设计的。
比如以分辨率 1920px * 1080px 来设计,以 density 为 3 来标注,也就是屏幕其实是 640dp * 360dp。如果我们想在所有设备上显示完全一致,其实是不现实的,因为屏幕高宽比不是固定的,16:9、4:3甚至其他宽高比层出不穷,宽高比不同,显示完全一致就不可能了。但是通常下,我们只需要以宽或高一个维度去适配,比如我们Feed是上下滑动的,只需要保证在所有设备中宽的维度上显示一致即可,再比如一个不支持上下滑动的页面,那么需要保证在高这个维度上都显示一致,尤其不能存在某些设备上显示不全的情况。同时考虑到现在基本都是以 dp 为单位去做的适配,如果新的方案不支持 dp,那么迁移成本也非常高。
因此,需求两点如下:
从dp和px的转换公式 :px = dp * density
可以看出,如果设计图宽为360dp,想要保证在所有设备计算得出的px值都正好是屏幕宽度的话,我们只能修改 density 的值。
先来熟悉下 DisplayMetrics 中和适配相关的几个变量:
下面假设设计图宽度是360dp,以宽维度来适配。
那么适配后的 density = 设备真实宽(单位px) / 360,接下来只需要把我们计算好的 density 在系统中修改下即可,代码实现如下:
同时在 Activity.onCreate 方法中调用下。代码比较简单,也没有涉及到系统非公开api的调用,因此理论上不会影响app稳定性。
如果用户修改了字体大小,这里字体并不会随着变化, 因为还需要修改 scaledDensity。
最终代码如下:
object ScreenUtil { fun adapterScreen(activity: Activity, targetDP: Int, isVertical: Boolean) { //系统的屏幕尺寸 val systemDM = Resources.getSystem().displayMetrics //app整体的屏幕尺寸 val appDM = activity.application.resources.displayMetrics //activity的屏幕尺寸 val activityDM = activity.resources.displayMetrics if (isVertical) { // 适配屏幕的高度 activityDM.density = activityDM.heightPixels / targetDP.toFloat() } else { // 适配屏幕的宽度 activityDM.density = activityDM.widthPixels / targetDP.toFloat() } // 适配相应比例的字体大小 activityDM.scaledDensity = activityDM.density * (systemDM.scaledDensity / systemDM.density) // 适配dpi activityDM.densityDpi = (160 * activityDM.density).toInt() } fun resetScreen(activity: Activity) { //系统的屏幕尺寸 val systemDM = Resources.getSystem().displayMetrics //app整体的屏幕尺寸 val appDM = activity.application.resources.displayMetrics //activity的屏幕尺寸 val activityDM = activity.resources.displayMetrics activityDM.density = systemDM.density activityDM.scaledDensity = systemDM.scaledDensity activityDM.densityDpi = systemDM.densityDpi appDM.density = systemDM.density appDM.scaledDensity = systemDM.scaledDensity appDM.densityDpi = systemDM.densityDpi } }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
Android ByteDance Screen adaptation
[TOC]
这篇文章讲解 Android 不同屏幕的适配方式
传统的 dp 适配方式的缺点
android 中的各种各种单位渲染之前都会转为 px。
上面的 dpi 根据屏幕真实的分辨率和尺寸来计算,每个设备都不一样。
屏幕尺寸,分辨路和像素密度
一般情况下,手机的分辨率是宽* 高,屏幕大小以 寸 为单位,关系如下:dpi * 屏幕密度 = 宽^2 + 高^2
比如:手机屏幕分辨率为 1920 * 1080, 屏幕尺寸为5寸的话, dpi = 440.
存在的问题
如上,加入设计图以 360dp 来设计。上面的屏幕实际为 1080/(440/160)= 392.7dp。
这种情况下, 即使用 dp 也无法做到在不同屏幕下可以显示同样的效果。同时还存在部分屏幕不足 360dp,显示不全的情况。
新的适配方式
一般我们设计图都是以固定的尺寸来设计的。
比如以分辨率 1920px * 1080px 来设计,以 density 为 3 来标注,也就是屏幕其实是 640dp * 360dp。如果我们想在所有设备上显示完全一致,其实是不现实的,因为屏幕高宽比不是固定的,16:9、4:3甚至其他宽高比层出不穷,宽高比不同,显示完全一致就不可能了。但是通常下,我们只需要以宽或高一个维度去适配,比如我们Feed是上下滑动的,只需要保证在所有设备中宽的维度上显示一致即可,再比如一个不支持上下滑动的页面,那么需要保证在高这个维度上都显示一致,尤其不能存在某些设备上显示不全的情况。同时考虑到现在基本都是以 dp 为单位去做的适配,如果新的方案不支持 dp,那么迁移成本也非常高。
因此,需求两点如下:
从dp和px的转换公式 :px = dp * density
可以看出,如果设计图宽为360dp,想要保证在所有设备计算得出的px值都正好是屏幕宽度的话,我们只能修改 density 的值。
先来熟悉下 DisplayMetrics 中和适配相关的几个变量:
最终方案
下面假设设计图宽度是360dp,以宽维度来适配。
那么适配后的 density = 设备真实宽(单位px) / 360,接下来只需要把我们计算好的 density 在系统中修改下即可,代码实现如下:
同时在 Activity.onCreate 方法中调用下。代码比较简单,也没有涉及到系统非公开api的调用,因此理论上不会影响app稳定性。
如果用户修改了字体大小,这里字体并不会随着变化, 因为还需要修改 scaledDensity。
最终代码如下:
The text was updated successfully, but these errors were encountered: