社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
这篇文章内容主要来自于Google的官方指导,有些地方加入笔者自己的理解。
有很多内容现在应用的已经很少了,比如ldpi屏幕。现在android设备的分辨率越来越高,尺寸也接近于同一,适配难度也低了很多。
Google在过去不断推出了新的View组件、容器组件。个人建议尽量使用新的组件来实现UI,它们往往性能更好,风格和样式趋近于MD的统一风格,而且更易于适配不同的屏幕。
但笔者仍然保留了低像素屏幕适配的部分。因为一些性能不高的设备上,仍可能在使用像素和密度较低的屏幕。
屏幕尺寸
按屏幕对角测量的实际物理尺寸。
为简便起见,Android 将所有实际屏幕尺寸分组为四种通用尺寸:小、 正常、大和超大。
屏幕密度
屏幕物理区域中的像素量;通常称为 dpi(每英寸 点数)。例如, 与“正常”或“高”密度屏幕相比,“低”密度屏幕在给定物理区域的像素较少。
为简便起见,Android 将所有屏幕密度分组为六种通用密度: 低、中、高、超高、超超高和超超超高。
方向
从用户视角看屏幕的方向,即横屏还是 竖屏,分别表示屏幕的纵横比是宽还是高。请注意, 不仅不同的设备默认以不同的方向操作,而且 方向在运行时可随着用户旋转设备而改变。
六种通用的密度:
密度独立性
保持密度独立性很重要,因为如果没有此功能,UI 元素(例如 按钮)在低密度屏幕上看起来较大,在高密度屏幕上看起来较小。这些 密度相关的大小变化可能给应用布局和易用性带来问题。
上图表示:不支持不同密度的示例应用在低、中、高密度屏幕上的显示情况。
上图表示:良好支持不同密度(密度独立)的示例应用在低、中、高密度屏幕上的显示情况。
Android 支持多种屏幕的基础是它能够管理针对当前屏幕配置 以适当方式渲染应用的布局和位图 可绘制对象。
系统可处理大多数工作,通过适当地 缩放布局以适应屏幕尺寸/密度和根据屏幕密度缩放位图可绘制对象 ,在每种屏幕配置中渲染您的应用。
<supports-screens>
layout-xlarge/
。sw<N>dp
配置限定符来定义布局资源可用的最小宽度。例如,如果多窗格平板电脑布局需要至少 600dp 的屏幕宽度,应将其放在 layout-sw600dp/
中。在项目的 res/ 目录中新建一个目录,并使用以下 格式命名: -
您可以一次使用多个 — 只需使用短划线分隔每个 限定符。
将适当的配置特定资源保存在此新目录下。这些资源 文件的名称必须与默认资源文件完全一样。
示例:
res/layout/my_layout.xml // layout for normal screen size ("default")
res/layout-large/my_layout.xml // layout for large screen size
res/layout-xlarge/my_layout.xml // layout for extra-large screen size
res/layout-xlarge-land/my_layout.xml // layout for extra-large in landscape orientation
res/drawable-mdpi/graphic.png // bitmap for medium-density
res/drawable-hdpi/graphic.png // bitmap for high-density
res/drawable-xhdpi/graphic.png // bitmap for extra-high-density
res/drawable-xxhdpi/graphic.png // bitmap for extra-extra-high-density
res/mipmap-mdpi/my_icon.png // launcher icon for medium-density
res/mipmap-hdpi/my_icon.png // launcher icon for high-density
res/mipmap-xhdpi/my_icon.png // launcher icon for extra-high-density
res/mipmap-xxhdpi/my_icon.png // launcher icon for extra-extra-high-density
res/mipmap-xxxhdpi/my_icon.png // launcher icon for extra-extra-extra-high-density
替代布局
一般而言,在不同的屏幕配置上测试应用后,您会知道是否需要用于不同屏幕尺寸的替代布局。例如:
在超大屏幕上测试时,可能会发现您的布局无法 有效地利用大屏幕,并且明显拉伸填满屏幕。
在此情况下,您应该为超大屏幕提供替代布局,以提供 针对大屏幕(例如平板电脑)优化、重新设计的 UI。
虽然您的应用不使用替代布局也能在大屏幕上正常运行,但 必须让用户感觉您的应用看起来像是专为其 设备而设计。如果 UI 明显拉伸,用户很可能对 应用体验不满意。
简而言之,您应确保应用布局:
替代可绘制对象
要为不同的密度创建替代位图可绘制对象,应遵循六种通用密度之间的 3:4:6:8:12:16 缩放比率。例如,如果您的 位图可绘制对象是对中密度屏幕使用 48x48 像素,则所有不同的尺寸应为:
示例:如果 600dp 是平板电脑布局支持的最小可用宽度,可以提供以下两 组布局:
res/layout/main_activity.xml # 手机
res/layout-sw600dp/main_activity.xml # 平板
在此情况下,可用屏幕空间的最小宽度必须是 600dp,才可 应用平板电脑布局。
示例: 对于要进一步自定义 UI 以区分不同尺寸(例如 7 英寸和 10 英寸平板电脑)的其他情况,可以定义其他最小宽度布局:
res/layout/main_activity.xml # 手机
res/layout-sw600dp/main_activity.xml # 7寸平板,最小600dp宽
res/layout-sw720dp/main_activity.xml # 10寸平板 最小700dp宽
使用“最小宽度”限定符sw<N>dp
,用于指定屏幕两边的最小值,而不管设备当前的方向如何。
使用sw<N>dp
是指定布局可用于整体屏幕尺寸的简便方法,它会忽略屏幕的方向。
有时必须确定布局当前可用的精确宽度或高度。比如屏幕只要600dp的宽度时,就并排显示两个片段的双窗格布局,无论横屏还是竖屏。此时,可以使用下面的配置:
res/layout/main_activity.xml # 手机
res/layout-w600dp/main_activity.xml # 多窗格,只要屏幕宽度达到600dp(无论横屏竖屏)
<supports-screens>
的一些属性:
1. android:requiresSmallestWidthDp
:指定需要的最小宽度或高度
- 示例,如果应用只用于最小可用宽度为 600dp 的平板电脑样式设备:
```
<manifest ... >
<supports-screens android:requiresSmallestWidthDp="600" />
...
</manifest>
```
2. android:compatibleWidthLimitDp
:指定用户支持的最大“最小宽度”,将屏幕兼容性模式用作用户可选的功能。
- 如果设备可用屏幕的最小宽度大于这个值,用户仍可安装应用,但提议在屏幕兼容性模式下运行。
- 默认情况下,屏幕兼容性模式会停用,并且布局照例会调整大小以适应屏幕,但按钮会显示在系统栏中,可让用户打开和关闭屏幕兼容模式。
- 如果应用可针对大屏幕正确调整大小,则无需使用此属性。建议不要使用此属性,而是确保布局针对较大屏幕调整大小。
3. android:largestWidthLimitDp
:指定应用支持的最大“最小宽度”来强制启用屏幕兼容性模式。
- 如果设备可用屏幕的最小宽度大于这个值,应用将在屏幕兼容性模式下运行,且用户无法停用该模式。
对布局尺寸使用 wrap_content
、match_parent
或 dp 单位
不要在代码中使用硬编码的像素值
使用尺寸和密度特定资源
res/drawable-mdpi/icon.png //中等密度屏幕的icon,100px的图片
res/drawable-hdpi/icon.png //高密度屏幕的icon,150px的图片
系统预缩放机制:
预缩放机制的一些问题:
如果请求预缩放的资源的尺寸,系统将返回缩放后尺寸的值。
例如,针对 mdpi 屏幕以 50x50 像素 设计的位图在 hdpi 屏幕上将扩展至 75x75 像素(如果没有 用于 hdpi 的备用资源),并且系统会这样报告大小。
避免预缩放:
如果不希望系统预缩放资源,可以将资源放在res/drawable-nodpi/
中:
res/drawable-nodpi/icon.png
当系统使用icon.png 位图时,不会根据当前设备密度缩放。
<supports-screens>
中奖android:anyDensity
设置为 false
BitmapFactory
加载图片时,将 inScaled
设置为 false
,即可对图片停用预缩放,启用自动缩放。对Bitmap
调用setDensity()
来指定密度,参数从DisplayMetrics
选择密度常量。
如果bitmap不指定密度,系统会对bitmap应用“自动缩放”:
系统加载bitmap时,默认情况下假设位图是针对基线中密度(mdpi)屏幕而设计,然后在绘制时自动缩放位图。
BitmapFactory.Options
来定义bitmap的属性,来确定系统是否要缩放或者如何缩放。 inScaled
设置为false
,系统不会进行预缩放,而在绘制时使用自动缩放。我们永远不推荐在代码中使用px值。如有需要,请将px转换为dp。
// 手势移动像素数
private static final float GESTURE_THRESHOLD_DP = 16.0f;
// 获取屏幕密度比值
final float scale = getResources().getDisplayMetrics().density;
// dp转px
mGestureThreshold = (int) (GESTURE_THRESHOLD_DP * scale + 0.5f);
转换时加上 0.5f,将该数字四舍五入到最接近的整数。
DisplayMetrics.density
根据当前屏幕密度指定dp转px使用的缩放系数。
使用预缩放的配置值
使用 ViewConfiguration
类访问 Android 系统使用的通常距离、 速度和时间。比如,getScaledTouchSlop()
可获取框架用作滚动阈值的距离(像素):
private static final int GESTURE_THRESHOLD_DP =
ViewConfiguration.get(myContext).getScaledTouchSlop();
使用AVD Manager创建各种尺寸、像素、屏幕密度、Android版本的模拟器,还有很多设备特性可以自定义。
也可以使用Genymotion来创建模拟器。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!