转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持!
原文链接:http://developer.android.com/guide/practices/screens_support.html
支持多屏
Android涉及各种各样的支持不同屏幕尺寸和密度的设备。对于应用程序,Android系统通过设备和句柄提供了统一的开发环境。大部分工作是校正每个应用程序的用户界面到它显示的屏上。与此同一时候,系统提供APIs同意你控制应用界面为特定的屏幕尺寸和密度。为不同屏幕的配置提供最优化的用户界面设计。
比如,你可能会要一个平板电脑的用户界面。这不同于手机的用户界面。
尽管系统能缩放。调整其尺寸,以使应用软件工作在不同屏上,可是应该尽量优化应用软件适应不同的屏幕尺寸和密度。为此。对全部设备的用户体验应最大化且应让用户们相信应用软件是真正为他们的设备设计的,而不是简单的拉伸使屏适合他们的设备。
依照文中描写叙述的做法。通过使用一个apk文件,能够创建一个应用软件能恰当显示并在全部的支持屏配置中提供最优用户体验。
多屏支持概述
本节提供了Android支持多屏的概述,包含:介绍了本文中API用到的术语和概念,总结了系统支持的屏设置,概述了API和以下的屏幕兼容特性。
术语和概念
屏幕尺寸
- 实际的物理尺寸,是依照屏幕的对角线计量的。www.saige.com/shop/auction-27230.htm
- 为简单起见。Android把全部的屏幕尺寸划分为四种广义的尺寸:小、标准、大。特大号。
屏幕密度
- 屏幕占领的物理区域所含像素的个数;通常被称为dpi(每英寸点数).
- 比如在给定的物理区域中,与“标准的”或“高”密度屏幕相比。低密度屏幕具有较少的像素。
方向
- 屏幕的方向来自于用户的角度。这是横向或纵向,分别指屏幕各个角度的比例,而不是宽或高。须要注意的是,不仅不同的设备在不同方向执行,并且当用户旋转设备时,方向也同一时候在改变。
分辨率
- 屏幕上物理像素的总数。支持多屏时。应用程序不直接与分辨率有关,应用程序应该仅仅关心屏幕的尺寸和密度,用指定的广义的尺寸和密度组。
dp
- 一种有效的在定义UI布局时你应当使用的像素单位。以一种密度无关的方式表示布局的尺寸或者位置。
- dp相当于160dpi屏幕,它是系统为“中等的”密度屏设定的基准密度。同一时候,系统透明地处理不论什么一种dp单位。必要时,基于使用中的屏的实际密度。dp单位依据公式 px = dp * (dpi / 160)简单地转化为屏像素。比如,一个240dpi的屏幕,1 dp等于1.5个物理像素。定义应用程序的UI时。你应该总是使用dp单位,以确保在不同密度的屏幕上正确地显示你的UI。
支持的屏幕范围
从Android1.6(API等级为4)開始。Android提供了支持多个屏幕的尺寸和密度。表明一种设备拥有很多不同的屏幕配置。你应该利用Android系统的这些特性去为每个屏幕配置优化你的应用程序界面,并且应确保你的应用程序不仅能正常执行,并且应尽可能地在每个屏幕上提供最好的用户体验。
为了简化为多个屏的用户界面设计方式。Android系统将实际的屏幕尺寸和密度范围划分为:
- 一组广义的尺寸:小。标准。大,特大号。
注:从Android3.2(API等级为13)起,这些尺寸分组已被弃用,大家支持的是一种新的基于可用屏幕宽度的管理屏幕尺寸的技术。
假设你正在开发Android3.2或者更高版本号。參见Android3.2平板电脑布局章节获取很多其它信息。
- 一组四个广义的密度:ldpi (低), mdpi (中等), hdpi (高),和 xhdpi (超高)。
这样的广义的尺寸和密度是环绕一种基准的配置进行划分的,这样的基准的配置是指一个标准尺寸和mdpi (中等)密度。这个基线是基于第一个Android 上电设备。T-Mobile G1的屏幕配置。它具有HVGA屏幕(直到Android1.6,这是Android支持的唯一的屏幕配置)。
每一个广义的尺寸和密度跨越一套实际屏幕尺寸和密度。比如,当用手測量时。两种标准的屏幕尺寸的设备可能具有实际的略微不同的屏幕尺寸和纵横比。
相同。两种hdpi屏幕密度的设备可能包括略微不同的实际像素密度。
Android制造这些差异使应用程序抽象化。所以,你能够提供设计的UI给广义的尺寸和密度。必要时让系统处理不论什么最后的调整。
图1 阐明了不同的尺寸和密度被怎样大致归类到不同的尺寸和密度组。
图1 阐明了不同的尺寸和密度被怎样大致归类到不同的尺寸和密度组
当为不同的屏幕尺寸设计UI时,会发现每个设计须要最低限度的空间。
因此,上面提到的每个广义的屏幕尺寸都有系统定义的相关联的最小分辨率。这些最小尺寸在“dp”单位内。当设计布局时。应当使用同样的单位。
- 超大屏幕至少960dp x720dp
- 大屏幕至少640dp x480dp
- 标准屏幕至少470dp x320dp
- 小屏幕至少426dp x320dp
注:在Android3.0之前,这些最小屏幕尺寸没有非常好的定义,所以可能会遇到一些在标准和大之间被错误归类的设备。这些也是基于屏幕的物理分辨率,因此各种不同样的设备也会遇到前面的问题。比如。一个有系统栏的1024x720平板会留少一点可用的空间给应用程序。
为了优化应用程序的UI适应不同的屏幕尺寸和密度。能够提供不论什么广义的尺寸和密度替代资源。一般来说,应当提供替代布局给不同屏幕尺寸和替代的位图图像给不同的屏幕密度。在执行时,基于当前设备屏幕的广义的尺寸或密度,系统会为你的应用程序使用适当的资源。
没有必要提供替代资源给每一个屏幕尺寸和密度的组合。系统提供了强大的兼容特性,这些特性会处理大部分工作使你的应用程序呈如今不论什么设备的屏幕上,前提是已经通过使用同意它适当地调整尺寸的技术实现了UI(正如以下最佳实践中描写叙述的)。
注:定义一种设备的广义的屏幕尺寸和密度特性是彼此相互独立的。
比如。一种WVGA高密度屏幕被觉得是标准尺寸的屏幕,是由于它的物理大小与T-Mobile G1(Android的第一个设备和基准屏幕设置)大约同样。
还有一方面。一种 WVGA中等密度的屏幕被觉得是大尺寸的屏幕。虽然它有同样的分辨率(同样数量的像素),这样的WVGA中等密度的屏幕有更低的屏幕密度,意思是每一个像素比較大,因此。整个屏幕比基准(标准尺寸)屏幕要更大。
密度无关性
当应用程序保留了用户界面元素的物理尺寸以不同的密度显示在屏幕上(从用户的角度来看)时,它实现了“密度无关性”。 维护密度无关系性非常重要,由于,假设没有它。一个UI元素(如button)在一个低密度屏幕上看起来较大而在一个高密度屏幕上看起来非常小。
这种密度相关的尺寸的改变影响应用程序的布局和使用。
图2和图3 分别展示了当它不提供密度无关性和提供了密度无关性时。应用程序之间的差异。
图2 当不提供密度无关性,应用程序在低、中等、高密度屏幕上显示实例
图3 当提供密度无关性。应用程序在低、中等、高密度屏幕上显示实例
Android系统通过下面两种方式帮助应用程序实现密度无关性:
- 系统为当前屏幕密度调整dp单位到适当的值
- 如有必要,系统会依据当前屏幕密度调整画图资源到适当的尺寸
在图2中。文本视图和位图画图有规定的尺寸的像素(像素单位)。因此这些视图在低密度屏幕上看起来较大。在高密度屏幕上看起来较小。这是由于虽然实际的屏幕尺寸是一样的,可是高密度屏每英尺有较多的像素(同样数量的像素适合于较小区域)。
在图3中,布局的尺寸被指定为密度无关性像素(dp 单位)。由于密度无关性像素的基线是中等密度的屏幕,一个有中等密度屏幕的设备看上去与图2中的一样。对于低密度和高密度屏幕而言。无论如何,系统能分别减少、调高密度无关性像素的值去恰当地适应屏幕。 在大多数情况下。你能够简单地在密度无关性像素里(dp
单位)指定全部的布局尺寸或者恰当地“包装内容”来确保应用程序的密度无关性。然后系统会依据恰当的缩放因子为当前屏幕密度调整位图视图以适当的尺寸显示出来。
可是。位图缩放会导致图片模糊,如上面的截图。为了避免这些问题,应该为不同的密度提供替代位图资源。比如,应该给高密度屏幕提供更高分辨率的位图,系统会使用它们,而不是使用为中等密度屏幕设计的缩放位图。下面段落将介绍很多其它关于怎样提供不同替代资源给不同的屏幕配置。
怎样支持多屏
Android支持多屏的基础是它可以以适当的方式为当前屏幕设置管理应用程序的布局和位图画图的渲染。依据实际情况,系统通过缩放布局去适应屏幕的尺寸/密度和为屏幕密度缩放位图画图。处理大部分工作去适当地渲染应用程序到每个屏幕配置。然而,为了更好地处理不同屏幕配置,应该: *在清单文件里明白申明应用程序支持哪种屏幕大小
通过申明应用程序支持哪种屏幕尺寸。能够确保仅仅有支持的屏幕尺寸的设备才干下载应用程序。
声明支持不同屏幕尺寸也会影响系统怎样在较大屏幕上执行应用程序。尤其是。不论应用程序是否执行在屏幕兼容模式。 为了申明应用程序支持的屏幕大小,应该在manifest文件里包括<supports-screens>的元素。
*为不同的屏幕尺寸提供不同的布局
默认情况下,Android会又一次调整应用布局去适合当前设备屏幕。在大多数情况下,这样做非常好。
在其他情况下。UI可能看上去不太好且可能不同屏幕尺寸须要调整。比如。在较大屏幕上。可能会调整某些元素的位置和尺寸去充分利用额外的屏幕空间,或者在一个较小屏幕上,会调整尺寸使得一切都能够在屏幕上显示。 能够提供指定大小资源的配置限定符。有小、标准、大、超大。
比如,一个超大屏幕的布局应该选Xlarge。 从Android3.2(API等级为13)起,上面的尺寸分组已被弃用,你应该使用sw<N>dp配置限定符去定义布局资源须要的最小的可用的宽度。比如,假设多窗格平板布局须要至少600dp的屏幕宽度,应该选sw600dp。使用新技术申明布局资源将会在Declaring
Tablet Layouts for Android 3.2章节讨论。
*为不同的屏幕密度提供不同的位图画图
默认情况下,Android调整你的位图画图(.png, .jpg, and .gif 文件)和9补丁画图(.9.png 文件),让他们在每一个设备上以适当的物理尺寸呈现。比如。你用程序仅仅为基线、中等屏幕密度(mdpi)提供了位图画图,系统会调高高密度屏幕。减少低密度屏幕。这些调整会导致图片不真实。为了确保图片看起来最好,应当在不同分辨率下包括替代版本号去适应不同的屏幕密度。能够用来指定密度资源的配置限定符有ldpi(低)、mdpi (中等), hdpi (高), and xhdpi (超高)。比如,高密度屏幕的位图应该选hdpi。
尺寸和密度配置限定符与上面的支持的屏幕范围中描写叙述的广义尺寸和密度一致。
凝视:假设你不太熟悉配置限定符且不知道系统怎样使用他们应用替代资源的话。请阅读Providing Alternative Resources章节获取很多其它信息。 在执行时,对于不论什么给定的资源,系统通过下面步骤实如今当前屏幕上获取最佳的显示:
1.系统使用适当的替代资源
基于当前屏幕的尺寸和密度,系统会使用应用程序里的不论什么指定尺寸和密度的资源。比如,假设设备有一个高密度屏幕且应用程序请求画图资源时。,系统会在画图资源文件夹寻找最匹配的设备配置。依赖于其它可用的替代资源。一个有hdpi限定符的资源文件夹(如 drawable-hdpi)可能是最匹配的,因此系统使用这个文件夹中的画图资源。
2.假设没有匹配的资源可用,系统会使用默认资源且会调高或减少资源去匹配当前屏幕的尺寸和密度这些“默认”资源是指那些没有配置限定符标记的资源。
比如在drawable/中的资源就是默认的画图资源。系统假定默认资源是为基准屏幕尺寸和密度设计的,即标准屏幕尺寸和中等密度。比如,系统会恰当地为高密度屏幕调高默认密度资源,为低密度屏幕减少默认资源。
然而,当系统在寻找一个指定密度的资源且在指定密度文件夹没找到它时。它不会总是使用默认资源。为了获取更好的效果,系统会使用一个其它指定密度资源。比如,当系统在寻找一个低密度资源且这个资源是不可用时,系统更喜欢减少高密度版本号的资源,由于系统能够简单地乘以0.5系数将高密度资源减少为低密度,与调整中等密度资源乘以0.75系数相比。这样用到非常少的工件。
关于Android是怎样通过匹配配置限定符到设备配置来选择替代资源的很多其它信息,请阅读How
Android Finds the Best-matching Resource章节。
使用配置限定符
Android支持多种配置限定符。让你控制系统怎样基于当前设备屏幕的特征选择替代资源。一个配置限定符是一个字符串,你能够把它附加到你的Androidproject的资源文件夹中并指定里面的资源是为此配置设计的。
为了使用配置限定符:
1.在你的project的res文件夹创建一个新文件夹,并使用格式命名:
- <resources_name>-<qualifier>
- <resources_name>是标准的资源名称(如drawable or layout)。
- <qualifier>是以下表1中的配置限定符。指定这些资源将要被用的屏幕配置(如hdpi or xlarge)。
2.保存这些适当的指定配置的资源到这个新文件夹。这些资源文件的命名必须严格与默认的资源文件名称一样.
比如。xlarge是用于超大屏幕的配置限定符。当你加入这些字符串到一个资源文件夹名(如layout-xlarge)时。它告诉系统这些资源将被用到有超大屏幕的设备上。
表1 同意你提供指定资源给不同屏幕配置的配置限定符
Screen characteristic | Qualifier | Description |
---|---|---|
Size |
small |
Resources for small size screens |
normal |
Resources for normal size screens. (This is the baseline size.) |
|
large |
Resources for large size screens. |
|
xlarge |
Resources for extra large size screens |
|
Density |
ldpi |
Resources for low-density (ldpi) screens (~120dpi). |
mdpi |
Resources for medium-density (mdpi) screens (~160dpi). (This is the baseline density.) |
|
hdpi |
Resources for high-density (hdpi) screens (~240dpi). |
|
xhdpi |
Resources for extra high-density (xhdpi) screens (~320dpi). |
|
nodpi |
Resources for all densities. These are density-independent resources. The system does not scale resources tagged with this qualifier, regardless of the current screen‘s density. |
|
tvdpi |
Resources for screens somewhere between mdpi and hdpi; approximately 213dpi. This is not considered a "primary" density group. It is mostly intended for televisions and most apps shouldn‘t need it—providing mdpi and hdpi resources is sufficient for most apps and the system will scale them as appropriate. If you find it necessary to provide tvdpi resources, you should size them at a factor of 1.33*mdpi. For example, a 100px x 100px image for mdpi screens should be 133px x 133px for tvdpi. |
|
Orientation |
land |
Resources for screens in the landscape orientation (wide aspect ratio). |
port |
Resources for screens in the portrait orientation (tall aspect ratio). |
|
Aspect ratio |
long |
Resources for screens that have a significantly taller or wider aspect ratio (when in portrait or landscape orientation, respectively) than the baseline screen configuration. |
notlong |
Resources for use screens that have an aspect ratio that is similar to the baseline screen configuration. |
注:假设在Android3.2或者更高版本号上开发应用程序。请參阅Declaring Tablet Layouts for Android 3.2章节获取关于新的配置限定符的信息,当申明了指定屏幕尺寸(而不是使用表1中的尺寸限定符的布局资源时,你应当使用这些限定符。
获取很多其它关于这些限定符怎样大致相应于真实的屏幕尺寸和密度的信息。请參阅本文中前面提到的支持的屏幕范围章节。
比如,以下是应用程序中的资源文件夹列表。这个程序为中等、高及超高密度屏幕提供了不同的为不同屏幕尺寸和位图画图设计的布局。 res/layout/my_layout.xml // 标准屏幕尺寸的布局("默认") res/layout-small/my_layout.xml // 小屏幕尺寸的布局 res/layout-large/my_layout.xml // 大屏幕尺寸的布局 res/layout-xlarge/my_layout.xml //超大屏幕尺寸的布局 res/layout-xlarge-land/my_layout.xml
// 横向超大的屏幕布局
res/drawable-mdpi/my_icon.png // 中等密度的位图 res/drawable-hdpi/my_icon.png //高密度的位图 res/drawable-xhdpi/my_icon.png // 超高密度的位图
如须要很多其它关于怎样使用替代资源和完整的配置限定符列表(不不过屏幕配置)的信息,请參阅Providing Alternative Resources。
请注意,当Android系统挑选资源时。它採用一定的逻辑来判定“最匹配”资源。
也就是说,使用的限定符不是必需在全部情况下,为了系统能用到它而严格匹配当前屏幕配置。详细来说,当基于尺寸的限定符选择资源时,假设没有更匹配的资源,系统会使用比当前屏幕更小的屏幕资源(比如,必要时,大尺寸屏幕将会使用标准尺寸屏幕资源)。可是,假设唯一可用的屏幕资源比当前屏幕大,系统将不会使用它们,并且假设没有其它匹配设备的配置的话,应用程序将会崩溃(比如。假设全部布局资源都被标记为xlarger限定符,可是设备是一个标准尺寸的屏幕)。很多其它关于系统怎样选择资源的信息,请阅读How
Android Finds the Best-matching Resource章节。
小提示:假设你有一些系统从未调整过的画图资源(也许由于在执行时对其进行了调整),应当把他们放置在nodpi配置个限定符的文件夹。有这些限定符的资源被觉得是密度不可知的资源。系统将不会调整它们。
设计可替代的布局和画图
应该创建的可替代资源的类型取决于应用程序的须要。
通常,应该使用尺寸和方向限定符提供可替代的布局资源。使用密度限定符去提供替代的位图画图资源。 以下的段落分别总结了应该怎样使用尺寸和密度限定符来提供替代的布局和画图。
可替代的布局
普通情况下,一旦在不同屏幕配置上測试应用程序。应该知道是否须要为不同屏幕尺寸创建可替代的布局。
比如:
- 当在小屏幕上測试时,可能会发现,布局不是非常适合这个屏幕。比如。一排button可能不适合在小屏幕的设备的屏幕宽度内。这样的情况下,应该为小屏幕提供一种可替代的布局,即通过调整这些button的大小或位置。
- 当在超大屏幕上測试时,可能会意识到。布局并没有有效地利用大屏幕,而是通过拉伸来填充它。在这样的情况下,应该为超大屏幕提供一种可替代的布局,就可以通过提供一种又一次设计的最合适于较大屏幕如平板的UI。
尽管应用程序应当能够在没有可替代布局的大屏幕上工作正常。可是,对用户来说,程序看起来好像是专门为他们的设备设计的这一点非常重要。假设是非常明显被拉伸的UI,用户相应用程序体验会更加不惬意。
- 并且,当在横向測试时可能会注意到,与纵向相比較,放置在纵向屏幕底部的UI元素应该是在横向屏幕的右側。
简而言之。应该确保应用程序的布局:
- 适合在小屏幕上(这样用户真正使用应用程序)
- 优化大屏幕。充分利用额外的屏幕空间
- 优化横向和纵向两个方向
假设在系统调整了布局后,UI要使用合适大小的位图(如button的背景图片)。应当使用九补丁的位图文件。九补丁文件基本是一个指定的可拉伸的二维PNG文件。当系统须要调整正在使用的位图的视图时,系统会拉伸九补丁位图,但仅延伸指定区域。
相同地,没有必要提供不同的画图给不同的屏幕尺寸。由于九补丁位图能调整不论什么大小。
然而,应当提供可替代的九补丁文件的版本号给不同屏幕密度。
可替代的画图
差点儿每一个应用程序应该有相应于不同屏幕密度的可替代的画图资源,由于差点儿每一个应用程序都有一个启动图标。并且图标应该在全部屏幕密度上看起来都非常好。相同,假设在应用程序中包括了其它位图画图(如菜单图标或应用程序的其它图像),应当提供可替代的版本号或者每一个版本号给不同的密度。
注:仅仅须要给位图文件((.png, .jpg, or .gif)和九补丁文件(.9.png)提供指定密度的画图。假设你使用XML去定义形状,颜色或者其它画图资源,应该在默认的画图文件夹(drawable/)做一个备份。
图4支持每一个密度的位图画图的相对尺寸
为了给不同密度创建可替代的位图画图,应该遵循基于四种广义密度的3:4:6:8的缩放比例。
比如。你有一个48x48像素的中等密度屏幕的位图画图(一个启动图标的尺寸),全部不同的尺寸应该是:
- 36x36适合于低密度
- 48x48适合于中等密度
- 72x72适合于高密度
- 96x96适合于超高密度
获取很多其它关于设计图标的信息。请參阅the Icon Design Guidelines。文中包括了各种位图画图的尺寸信息,如启动图标,菜单图标。状态栏图标,选项卡图标等等。
Android3.2平板布局的声明
对于第一代执行在Android3.0上的平板,正确声明平板布局的方法是把他们放到一个有xlarge配置限定符的文件夹里(比如,res/layout-xlarge/)。
为了适应其它类型的平板和屏幕尺寸-尤其是7寸平板-Android3.2为很多其它离散的屏幕尺寸引进了一种新的指定资源的方式。这项新技术是基于你的布局须要的空间(如600dp的宽度),而不是试图让你的布局去适合广义的尺寸组(如large or xlarge)。
设计7寸平板的原因是非常复杂的,当时使用广义的尺寸组是指一个7寸的平板在技术上与一个5寸的手机在同一个组(大组)。
尽管这两个设备在尺寸上看上去非常接近,可是应用程序的UI的空间是显著不同的。用户交互的风格也是如此。因此,一个7寸和5寸的屏不应该总是使用同一个布局。为了把提供两种不同屏的布局变成可能,Android如今同意你基于宽度与/或者高度指定布局资源。在dp单位中指定,这对于应用程序布局非常有效。
比如,在已经设计好了要用于平板类型的设备的布局后,当屏幕少于600dp宽时,可能会决定让布局停止工作。
这个阈值因此会成为平板布局须要的最小尺寸。照此,如今会指定这些布局资源应当能被使用。只在应用程序的UI有至少600dp宽度可用时。
应该要么选择宽度,并把它设计为最小尺寸,要么測试布局一旦完毕时。它支持的最小宽度是多少。
注:请记住,全部的这些新尺寸的APPs使用的数字都是密度无关性像素(dp)值,且布局的维度应该总是被定义使用dp单位。由于关心的是。系统占用屏幕密度后可用屏幕空间的数量。很多其它关于密度无关性像素的信息,请阅读文中前面提到的Terms and concepts。
新的尺寸限定符的使用
不同可以指定的基于布局的可用空间的资源配置的总结见表2。与传统的屏幕尺寸组(小、标准、大和超大)相比。这些新的限定符提供了很多其它的控制权在指定的应用程序支持的屏幕尺寸方面。
注:指定的使用这些限定符的尺寸不是实际的屏幕尺寸。
相反,在dp单位中的宽度或高度的尺寸对你的activity的窗体是可用的。Android系统可能会使用一些屏幕做系统UI(如屏幕底部的系统栏或顶部的状态栏),所以一些屏幕有可能对于你的布局是不可用的。
因此,你申明的尺寸应该是。特别是你的activity须要的尺寸-当申明了系统能提供给你的布局多少空间时。系统会占用不论什么被系统UI使用的空间。
还须要注意的是。工具栏被觉得是应用程序窗体空间的一部分,虽然你的布局没有申明。因此。系统会给布局缩减可用空间,在设计时必须考虑到这点。
表2 屏幕尺寸的新配置限定符(Android 3.2中介绍的)
Screen configuratione | Qualifier values | Description |
---|---|---|
smallestWidth |
sw<N>dp Examples: sw600dp sw720dp |
The fundamental size of a screen, as indicated by the shortest dimension of the available screen area. Specifically, the device‘s smallestWidth is the shortest of the screen‘s available height and width (you may also think of it as the "smallest possible width" for the screen). You can use this qualifier to ensure that, regardless of the screen‘s current orientation, your application‘s has at least <N> dps of width available for it UI. For example, if your layout requires that its smallest dimension of screen area be at least 600 dp at all times, then you can use this qualifer to create the layout resources, res/layout-sw600dp/. The system will use these resources only when the smallest dimension The smallestWidth of a device takes into account screen decorations and system UI. For example, if the device has some persistent UI elements on the screen that account for space along the axis of the smallestWidth, the system declares the smallestWidth to This is an alternative to the generalized screen size qualifiers (small, normal, large, xlarge) that allows you to define a discrete number for the effective size available for your UI. Using smallestWidth to determine the general screen size is useful because |
Available screen width |
w<N>dp Examples: w720dp w1024dp |
Specifies a minimum available width in dp units at which the resources should be used—defined by the <N> value. The system‘s corresponding value for the width changes when the screen‘s orientation switches between landscape and portrait to reflect the current actual width that‘s available for your UI. This is often useful to determine whether to use a multi-pane layout, because even on a tablet device, you often won‘t want the same multi-pane layout for portrait orientation as you do for landscape. Thus, you can use this to specify the minimum width required |
Available screen height |
h<N>dp Examples: h720dp h1024dp etc. |
Specifies a minimum screen height in dp units at which the resources should be used—defined by the <N> value. The system‘s corresponding value for the height changes when the screen‘s orientation switches between landscape and portrait to reflect the current actual height that‘s available for your UI. Using this to define the height required by your layout is useful in the same way as w<N>dp is for defining the required width, instead of using both the screen size and orientation qualifiers. However, most apps won‘t need this qualifier, considering that |
尽管使用这些限定符看上去比使用屏幕尺寸组更加复杂。可是当你一旦确定UI的需求后,这实际上应当更简单。
当设计UI时,可能关心的主要事情是。应用程序在手机类型的UI和多窗格的平板类型的UI之间切换时的实际尺寸。切换的关键在于特定的设计,或许须要720dp的宽度给平板布局,或许600dp已足够,或者480dp,或者其它位于这之间的数值。使用表2中的限定符。须要掌握布局改变时的精确尺寸。
很多其它关于这些尺寸配置限定符的讨论,请參阅Providing Resources文档。
配置实例
为了帮助实现一些为不同类型的设备设计的目标,以下是一些典型的屏幕宽度的数值:
- 320dp:一种典型的手机屏幕 (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, 等等).
- 480dp: 一种有点像条纹的中间态的平板 (480x800 mdpi).
- 600dp: 7寸平板 (600x1024 mdpi).
- 720dp: 10寸平板 (720x1280 mdpi, 800x1280 mdpi, etc).
使用表2中的这些尺寸限定符。应用程序能够在使用不论什么想要的宽度或高度的平板和手机的不同布局资源间切换。比如,假设平板布局支持的最小可用宽度是600dp。应该提高两套布局:
res/layout/main_activity.xml # 手机适用
res/layout-sw600dp/main_activity.xml #平板适用
在这样的情况下。为了使平板布局能用。可用的屏幕空间的最小宽度必须是600dp。
对于其它情况。你要进一步自己定义你的UI以区分如7寸和10寸平板的尺寸。能够定义额外的最小宽度布局:
res/layout/main_activity.xml # 适用于手机 (小于600dp的可用宽度)
res/layout-sw600dp/main_activity.xml #适用于7寸平板(大于等于600dp的可用宽度)
res/layout-sw720dp/main_activity.xml # 适用于10寸平板(大于或等于720dp的可用宽度)
请注意,第二套採用的“可用的宽度”限定符w<N>dp。通过这样的方式。一个设备可能实际上使用两种布局。这取决于屏幕的方向(假设在一个方向上可用的宽度是至少600dp,在还有一个方向上少于600dp)。
假设关心的是可用高度,能够相同使用h<N>dp限定符。
或者,假设情况比較特殊。甚至能够结合w<N>dp 和 h<N>dp一起使用。
支持屏幕尺寸的声明
一旦已经实现了不同屏幕尺寸的布局,在manifest文件里声明应用程序支持哪种屏幕也相同重要。
随同新的屏幕尺寸的配置限定符一起,Android3.2引进了新的<supports-screens> manifest元素属性。
android:requiresSmallestWidthDp
- 指定须要的最小smallestWidth。smallestWidth是必须能被应用程序的UI利用的屏幕空间的(在dp单位里)最小尺寸。也就是,最短的可用的屏幕的二维尺寸。因此,为了让设备与应用程序兼容,设备的smallestWidth必须大于等于这个值。(通常,不论屏幕当前的方向是什么。你提供的值是你的布局支持的“最小宽度”。
- 比如,假设应用程序是为600dp的最小可用宽度的平板类型设备设计的:
<manifest ... > <supports-screens android:requiresSmallestWidthDp="600" /> ... </manifest>
- 然而。假设应用程序支持全部Android支持的屏幕尺寸(如426dp x 320dp一样小)。那么没有必要申明这个属性。由于须要的最小宽度可能在不论什么设备上都是最小的。
注意:Android并不关心这个属性,因此它不会影响应用程序在执行时的行为。相反。它经常会为应用程序在服务如谷歌播放上进行过滤。
然而,谷歌播放眼下不支持过滤属性(在Android3.2上),因此。假设应用程序不支持小屏幕。应该继续使用其他尺寸的属性。
android:compatibleWidthLimitDp
- 这个属性同意通过指定应用程序支持的最大“最小宽度”将屏幕的兼容模式作为一个用户可选特征。假设设备的可用屏幕最小边大于这个值。用户仍然能够安装应用程序,可是不能在屏幕的兼容模式上执行。
默认情况下,屏幕的兼容模式是禁用的,和寻常一样,布局会被调整到适合屏幕,可是button在系统栏是可用的,它同意用户开启和关闭屏幕的兼容模式。
注:假设应用程序的布局正好适合大屏幕。就不是必需使用这个属性。
我们建议避免使用这个属性。而不是依照本文档中的建议确保布局适合更大屏幕。
android:largestWidthLimitDp
- 这个属性通过指定你的应用程序支持的最大“最小宽度”强制开启屏幕的兼容模式,假设设备的可用屏幕最小边大于这个值,应用程序会执行在屏幕兼容模式上,且用户没有办法去禁用它。
注:假设应用程序的布局正好适合大屏幕,就不是必需使用这个属性。我们建议避免使用这个属性,而不是依照本文档中的建议确保你的布局适合更大屏幕。
注意:当在Android3.2或者更高版本号上开发时。不应该使用较旧的屏幕尺寸属性并结合上面列出的属性。同一时候使用新属性和较旧的尺寸属性会导致不可预料的事情发生。
很多其它关于这些属性的信息。请查阅以上对应的链接。
最佳实践
支持多个屏幕的目的是为了创建一个能正常执行。且在不论什么Android支持的广义的屏幕配置上看起来都非常舒服的应用程序。本文的前面章节提供了关于Android怎样使应用程序适应屏幕配置和怎样在不同屏幕配置上自己定义应用程序的外观的信息。
这节提供了一些额外的技巧来确保应用程序适用于不同屏幕配置的技术。
以下是关于怎样确保你的应用程序可以恰当地显示在不同屏幕上的高速检查清单:
1.当在XML布局文件里指定尺寸时,使用wrap_content, fill_parent, 或者dp单位
2.在应用程序代码中不要使用硬编码的像素值
3.不要使用绝对布局(已被弃用)
4.对不同的屏幕密度採用可替代的位图画图
以下章节将讲述很多其它细节。
1.布局尺寸使用wrap_content, fill_parent, 或者 dp单位
当在XML布局文件里定义视图的android:layout_width和 android:layout_height时,使用wrap_content, fill_parent, 或者 dp单位以保证在当前设备屏幕上能给视图分配一个适当的尺寸。
比如,一个layout_width为100dp的视图在中等密度的屏幕上是100像素,在高密度屏幕上系统将把它调整到150dp。于是视图在屏幕上占用了大致同样的物理空间。
相同地,应该更喜欢用sp(与比例无关的像素)来定义文本的尺寸。Sp比例因子取决于用户的设置和系统调整的尺寸与它为dp调整的相同。
2.在应用程序代码中不要使用硬编码的像素值
出于性能方面的原因及为了保持代码更简单,Android系统採用像素作为尺寸或坐标值的标准单位。意思是,在代码中,视图的尺寸总是用像素表达。但总基于当前屏幕密度。比如,假设myView.getWidth()函数的返回值是10。在当前屏幕上视图有10个像素宽度,可是在更高密度屏幕的设备上。返回值可能是15.假设在你的应用程序代码中。使用像素值为位图的单位,且该位图不是为当前屏幕密度预先调整的,可能会调整这些在代码中你用以匹配未调整的位图源的像素值。
如果应用程序在执行时巧妙地处理位图或像素值。请參阅以下的章节Additional Density Considerations。
3. 不要使用绝对布局
不像其它的布局部件,绝对布局强制使用固定位置给子视图布局,这非常easy导致用户界面不能非常好地工作在不同的屏幕上。正由于如此,在Android1.5(API等级为3)中已经弃用了绝对布局。
相反。应该使用相对布局,它会使用相对位置为它的子视图布局。比如,能够指定button部件应该在文本部件的右側。
4.使用尺寸和指定密度资源
尽管系统会基于当前屏幕配置调整你的布局和画图资源。可是能够在不同屏幕尺寸上调整UI,且提供最优化的位图画图给不同密度。这在本文的前面已经重复强调过。
如果须要严格控制应用程序在各种屏幕配置上的显示情况,那么在指定配置资源文件夹中调整布局和位图画图。比如,如果希望图标显示在中等和高密度屏幕上。
简单地创建两个不同尺寸的图标(比如100x100用于中等密度。150x150用于高密度),把这两个变体放在适当的文件夹。使用适当的限定符:
res/drawable-mdpi/icon.png //适合于中等密度屏幕
res/drawable-hdpi/icon.png //适合于高密度屏幕
注:假设密度限定符未定义在文件夹名中,系统会假定在那个文件夹里的资源是为基线中等密度设计的,将会适当地为其它密度做调整。
很多其它关于有效的配置限定符的信息。请參阅本文前面结束的Using configuration qualifiers。
附加密度的注意事项
本节描写叙述了很多其它关于系统怎样在不同屏幕密度上调整位图画图、以及怎样更好地控制位图在不同密度上的显示信息。本节中的信息对大多数应用程序应该不是非常重要,除非应用程序在不同屏幕密度上执行时或者应用程序篡改了图像时,遇到了问题。
为了更好地了解在执行过程中改变了图像时怎样做到支持多密度,应该了解。系统通过下面几种方式确保合适的位图尺寸:
1.预先调整的资源(如位图画图)
- 基于当前屏幕的密度。系统使用应用程序中不论什么指定尺寸和密度的资源,并显示出来且不须要不论什么调整。假设资源在当前密度不可用。系统将会下载默认资源并调整他们使之适合于当前屏幕密度。系统觉得默认资源(无配置限定符文件夹的资源)是为基准屏幕密度(mdpi)设计的。除非它们是从指定密度资源文件夹下载的。
预先调整是指调整位图到当前屏幕密度适合的尺寸时系统所做的事情。
- 假设你请求预先调整好的资源的尺寸,系统会返回调整后代表该尺寸的值。比如,一个50x50 像素的mdpi屏幕的位图要在hdpi屏幕上扩大为75x75像素(假设此时没有可替代资源给hdpi),系统会这样返回此值。
- 有一些情况下,可能不须要Android的预先调整的资源。避免预先调整的最简单方式是将资源放置到nodpi配置限定符的文件夹中。比如:
- res/drawable-nodpi/icon.png
- 当系统使用这个目录中的icon.png位图时。它不会基于当前屏幕密度去调整该位图。
2.像素尺寸和坐标值的自己主动调整
- 应用程序能够通过在清单文件里设置android:anyDensity的属性为“假”或在程序中设置位图的inScaled值为“假”禁止预先调整资源。
在这样的情况下。系统在画图时会自己主动调整绝对像素的坐标值和像素尺寸。
这样做的目的是。为了确保已定义像素的屏幕元素仍然能以接近他们在基线屏幕密度(hdpi)上的物理尺寸显示出来。系统透明地处理这样的调整并把调整后的像素尺寸。而不是物理像素尺寸告诉应用程序。
- 比如,如果一个设备有WVGA高密度屏幕,即480x800,这与传统的HVGA屏幕的尺寸大约同样,可是它执行着已禁止预先调整资源功能的应用程序。
在这样的情况下,当系统在查找屏幕尺寸时,它会“欺骗”应用程序。给它返回值320x533(转化成屏幕密度接近mdpi)。然后,当应用程序開始画图操作时。如使矩形从(10,10) 扩大到 (100, 100)变成无效,系统通过缩放接近数量的值调整坐标。且把区域(15,15)
扩大到 (150, 150)变成无效。假设你的应用程序直接使用这个调整后的位图,这个误差会导致不可预期的行为,可是这被觉得是合理的折中的尽可能保持应用程序性能的方法。假设遇到这样的情况,请阅读以下关于Converting dp units to pixel units章节。
- 通常情况下。不应该禁止预先调整资源。支持多屏的最好方式是依照上面的How to Support Multiple Screens提到的基本技术操作。
假设应用程序在屏幕上以其他某种方式操作位图或与像素直接交互,你可能须要採取额外的步骤来支持不同屏幕密度。比如,假设你通过数手指划过时的像素值的方式响应触摸。你须要使用适当的密度无关性像素值。而不是实际的像素值。
调整执行时创建的位图对象
假设应用程序创建一个内存中的位图(位图对象),系统觉得这个位图是为基线中等密度屏幕设计的,默认情况下,在绘制时自己主动调整位图。当位图没有指定密度特性时,系统採用“自己主动调整”技术。假设没有正确地考虑到当前屏幕密度,也没有指定位图的密度特性。自己主动调整会导致人为缩放,这与没有提供可替代资源时一样。
为了控制在执行时创建的位图是否须要调整,你能够通过setDensity()指定位图的密度,从DisplayMetrics传递一个密度常量,比方DENSITY_HIGH 或 DENSITY_LOW。
假设正在创建一个使用BitmapFactory(如从文件或者流)的位图,能够使用BitmapFactory。选择定义一个已经存在的位图的特性,这决定系统是否或怎样调整位图。
比如。能够使用Density来定义位图是为哪种密度设计的,用Scaled去指定位图是否应该调整到匹配当前设备的屏幕密度。
假设设置Scaled为假,禁用了不论什么系统会用于位图的预先调整功能,系统在执行时将会自己主动调整它。
使用自己主动调整而不是预先调整会耗费很多其它CPU,可是占用更少的内存。
图5 预先调整和自己主动调整位图的演示比較结果
图5 演示了当在高密度屏幕上下载低(120)。中等(160) 和高 (240) 密度位图时。预先调整和自己主动调整机制的结果。差别是微妙的,由于全部的位图都被调整以匹配当前屏幕密度。然而调整过的位图的外观略微不同。这取决于在绘制时採用的是预先调整还是自己主动调整。你会找到此演示样例应用程序的源码,在ApiDemos里,演示了怎样使用预调整和自己主动调整位图。
注:在Android3.0或者以上版本号,因为图形框架的改进。预先调整和自己主动调整位图之间应该没有明显的差异。
-= 转换dp单位为像素单位 =-
在某些情况下。须要用dp来表示尺寸。然后把他们转换为像素。想象一下,在应用程序中滚动或者扔的手势在用户的手指划过至少16像素后才干被识别出。在基准屏幕上。在手势被识别出来之前,用户必须划过16像素除160dpi,这等于十分之中的一个英寸(或者2.5毫米)。在一个高密度屏幕(240dpi)设备上,用户必须划过16像素除240dpi。即十五分之中的一个英寸(或者1.7毫米)。这个距离相当短。因此对用户来说,程序看上去更加敏感。
要解决问题。手势阈值必须用dp表示,然后转换成实际的像素。
比如:
// The gesture threshold expressed in dp private static final float GESTURE_THRESHOLD_DP = 16.0f; // Get the screen‘s density scale final float scale = getResources().getDisplayMetrics().density; // Convert the dps to pixels, based on density scale mGestureThreshold = (int) (GESTURE_THRESHOLD_DP * scale + 0.5f); // Use mGestureThreshold as a distance in pixels...
依据当前屏幕密度,DisplayMetrics.density指定了你必须使用的将dp单位转为像素单位的比例因子。在一个中等密度屏幕上,DisplayMetrics.density等于1.0。在高密度屏幕上,DisplayMetrics.density等于1.5;在一个超高密度屏幕上,DisplayMetrics.density等于2.0;在低密度屏幕上,DisplayMetrics.density等于0.75.这个比例因子乘以dp单位得到的值就是当前屏幕的实际像素值(然后加入0.5f做四舍五入,转化的整数)。
很多其它信息,请參看DisplayMetrics类。
然而,不是为这里事件定义随意阈值。而是你应该使用预先调整的可从ViewConfiguration获取的配置值。
使用预先调整的配置值
能够使用ViewConfiguration类去訪问Android使用的共同的距离、速度和时间。比如。框架使用的作为滚动阈值的距离可通过getScaledTouchSlop()得到:
private static final int GESTURE_THRESHOLD_DP =ViewConfiguration.get(myContext).getScaledTouchSlop();
曾经缀getScaled开头的ViewConfiguration的方法保证返回值以像素为单位。不管当前屏幕的密度是什么,它都能正确显示。
怎样在多屏上測试你的应用程序
在公布应用程序之前,应该在全部支持的屏幕尺寸和密度上彻底地測试应用程序。Android的SDK包括了你能够使用的模拟器,它复制了应用程序能够执行的通用的屏幕配置的尺寸和密度。能够改动模拟器默认的尺寸,密度和分辨率以复制不论什么指定屏幕的特征。
使用模拟器和额外的自己定义配置让你能够測试不论什么可能的屏幕配置,因此不必买各种设备来測试应用程序支持的屏幕。
为了建立測试应用程序支持的屏幕环境,通过使用模拟器和模仿应用程序支持的屏幕的尺寸和密度的屏幕配置。应当创建一组AVDs(Android虚拟设备)。要做到这一点。能够使用AVD管理器去创建AVDs,然后以图形界面方式启动它们。
为了启动Android SDK管理器,在Android SDK文件夹(在windows上)运行SDK Manager.exe或者在<sdk>/tools/文件夹运行android。
图6展示了用来測试各种屏幕配置的选择了AVDs的AVD管理器。
图6展示了用来測试各种屏幕配置的选择了AVDs的AVD管理器。
很多其它有关创建和使用AVDs測试应用程序的信息。请參阅Managing AVDs with AVD Manager。
表3 Android SDK中从模拟器获取的各种屏幕配置和其他典型的分辨率
Low density (120), ldpi | Medium density (160), mdpi | High density (240), hdpi | Extra high density (320), xhdpi | |
---|---|---|---|---|
Small screen |
QVGA (240x320) |
480x640 |
||
Normal screen |
WQVGA400 (240x400)WQVGA432 (240x432) |
HVGA (320x480) |
WVGA800 (480x800) WVGA854 (480x854) 600x1024 |
640x960 |
Large screen |
WVGA800** (480x800)WVGA854** (480x854) |
WVGA800* (480x800) WVGA854* (480x854) 600x1024 |
||
Extra Large screen |
1024x600 |
WXGA(1280x800)? 1024x7681280x768 |
1536x1152 1920x1152 1920x1200 |
2048x1536 2560x1536 2560x1600 |
* 为了模仿此配置。在创建一个使用WVGA800或者WVGA854外观的AVD时指定.自己定义的密度为160. **为了模仿此配置。在创建一个使用WVGA800或者WVGA854外观的AVD时指定.自己定义的密度为120 ? 这个外观是Android3.0平台可用的.
想要知道支持不论什么给定屏幕配置的有源设备的相对数量,请參看屏幕尺寸和密度仪表板。
我们也建议在物理尺寸接近匹配的实际设备的模拟器上測试应用程序。这使得比較各种尺寸和密度上的測试结果变得很easy。
做到这点,须要知道电脑显示器(比如,30寸的Dell显示器的密度大约为960dpi)的以dpi为单位的近似密度。当从AVD管理器启动AVD时,能够在启动选项中,如图7所看到的,指定模拟器的屏幕尺寸和显示器的dpi。
图7 当从AVD管理器启动AVD时,你能设置的尺寸和密度
假设想在内置外观不支持的分辨率或密度的屏幕上測试应用程序,能够创建一个使用自己定义分辨率或密度的AVD。
在创建AVD时。应指定分辨率,而不是选择内置的外观。
假设正通过命令行启动AVD。能够指定通过选项參数-scale来指定比例。比如:
emulator -avd <avd_name> -scale 96dpi
为了改变模拟器的大小,能够通过參数选项选择想要的比例因子0.1-3实现。
很多其它关于从命令行创建AVDs的信息,请參阅Managing AVDs from the Command Line。