android屏幕适配

屏幕适配html

Android运行在提供不一样屏幕尺寸和密度的多种设备上。 对应用程序而言,Android系统提供一致的跨设备的开发环境而且处理适配不一样显示屏幕的大部分工做。同时,系统提供API,容许针对不一样的屏幕尺寸和密度来控制的应用程序UI,从而为不一样的屏幕配置来优化UI设计。android

尽管系统会进行缩放和调整,以使应用程序在不一样的屏幕上运行,仍然应该尽可能为不一样的屏幕尺寸和密度来优化应用。最大限度的为全部设备优化用户体验,这样用户才会认为应用程序是真正的为他们的设备设计的,而不是简单的拉伸或缩放来适应他们的设备。express

按照本文档中所述的作法,能够建立一个应用程序,使之在全部支持的屏幕配置上正确显示,并使用单一的.apk文件提供优化的用户体验。api

注:本文档中的信息假设应用程序是为Android 1.6API等级4)或更高版本设计。若是要应用程序支持Android 1.5或更低,请首先阅读 Strategies for Android 1.5

同时,要注意的Android 3.2推出新的API,更精确地控制应用程序使用不一样屏幕尺寸的布局资源。若是你正在开发为平板优化的应用程序,这些新功能尤为重要。有关详情,请参阅 为Android 3.2设计平板布局架构

屏幕支持概述app

本节概述Android对多个屏幕的支持,其中包括:在本文中和API中会用到的术语和概念的介绍,系统支持的屏幕配置的总括,以及API和底层屏幕适配特性的概览。框架

术语和概念less

屏幕尺寸ide

实际的物理尺寸,以屏幕的对角线为准。布局

为简单起见,将全部的实际尺寸分为四个广义的尺寸:small(小), normal(正常), large(大), extra large(特大)。

屏幕密度

屏幕的物理面积内的像素数量,一般指的DPI(每英寸点数)。例如,“低”的密度屏幕比“正常”或“高”密度屏幕在一个给定的物理面积内具备较少的像素。


为简单起见,将全部的实际密度分为四个广义的密度: low(低), medium(中等), high(高), extra high(超高)。

方向

从用户的角度来看,屏幕的方向。是横向或纵向,也就是说,屏幕的比例是高或者宽。须要注意的是,不只要在不一样的屏幕方向作不一样的操做,还要考虑到用户在运行时经过转动设备切换屏幕方向的状况。

分辨率

在屏幕上的物理像素总数。在支持多个屏幕时,应用程序不直接与分辨率相关;应用程序应该只与屏幕大小和密度相关。

密度无关的像素(DP)

在定义UI布局时应该使用的虚拟像素单元,它用一种密度无关的方式来表达布局尺寸或位置。

在160 dpi的屏幕上的一个物理像素,是“中等”的密度屏幕系统所承担的基准密度。系统在运行时透明地处理任何DP单位,必要时根据实际使用的屏幕密度缩放。 DP单位转换为屏幕像素是简单的:PX = DP *(DPI / 160)。例如,在240 dpi屏幕,1 DP等于1.5物理像素。定义应用程序的用户界面时,应该老是使用DP单位,以确保不一样密度的屏幕上正确显示UI。

屏幕支持范围

从Android 1.6(API Level 4)开始,Android提供了对多个屏幕尺寸和密度的支持,以反映出设备可能有的不一样的屏幕配置。可使用Android系统的功能,为每一个屏幕配置优化应用程序的用户界面,从而确保应用程序为每一个屏幕提供正常而且尽量最佳的用户体验。

为了简化为多种屏幕设计用户界面,Android划分了实际的屏幕尺寸和密度范围:

  • 广义的尺寸大小集合: small(小)normal(正常)large(大), and xlarge(超大)

注:从Android 3.2(API Level 13)开始,这种尺寸集合被废弃,取而代之的是一种基于可用屏幕宽度来管理屏幕尺寸的新技术。因此针对Android 3.2以及以上版本的开发,能够参考 为Android 3.2设计平板布局来获取更多信息。


  • 广义的密度集合: ldpi (), mdpi (), hdpi (), and xhdpi (超高)

广义的大小和密度都围绕一个基准配置,即正常的大小和MDPI(中)密度。这个基准配置即第一款Android设备的配置,此设备即拥有一个HVGA屏幕的T-Mobile G1(直到Android 1.6,这是Android支持的惟一的屏幕配置)。

每一个广义的大小和密度跨越了一系列实际的屏幕尺寸和密度。例如,两个设备,这两个设备报告的正常屏幕尺寸和宽高比可能与手工测量时略有不一样。一样,两个设备报告的hdpi的屏幕密度可能与真正的像素密度略有不一样。 Android抽象了应用程序的这些差别,所以能够提供广义的大小和密度设计的用户界面,让系统须要处理任何最终的调整。图1显示了不一样的大小和密度大体分类成不一样的大小和密度组。


图1. 解释了Android对实际的尺寸和密度到广义的尺寸和密度(数字是不许确的)的大体映射。

每个UI设计须要一个最小的空间,每个上文提到的广义的屏幕大小都拥有一个由系统定义的最小分辨率。这些空间是以“dp”为单位的,当定义布局时,也应当使用相同的单位,它使系统避免了对屏幕密度变化的顾虑。

  • xlarge 屏幕至少 960dp x 720dp

  • large 屏幕至少 640dp x 480dp

  • normal 屏幕至少 470dp x 320dp

  • small 屏幕至少 426dp x 320dp


为不一样屏幕尺寸和密度优化应用程序的用户界面,能够提供任何广义的大小和密度的alternative resources(选择性资源)。一般状况下,应该为不一样的屏幕尺寸提供alternative layouts而且为不一样的屏幕密度提供alternative bitmap images。在运行时,系统基于当前设备的广义屏幕尺寸或密度为应用程序采用适当的资源, 

不须要为每个屏幕大小和密度的组合提供选择性资源。系统提供了强大的兼容特性,能够处理在任何设备的屏幕上呈现应用程序的大部分工做,开发者只要实现UI技术,容许它正常调整。

: 定义广义屏设备的大小和密度的特色是相互独立的。例如,WVGA的高密度的屏幕被认为是一个正常大小的屏幕,由于它的物理尺寸是相同的T-Mobile G1(Android的设备和基线的屏幕配置)。另外一方面,WVGA的屏幕中密度被认为是一个大尺寸屏幕。虽然它提供了相同的分辨率(像素数相同),WVGA的屏幕中密度较低的屏幕密度,这意味着每一个像素的物理面积较大,所以,整个屏幕是比基准(正常大小)的屏幕更大。

密度的独立性

当应用程序在具备不一样密度的屏幕上显示时,它保留了用户界面元素(从用户的角度来看)的物理尺寸,即实现了“密度独立”。

保持密度的独立性是很是重要的,由于,没有它,一个UI元素(如按钮),在低密度屏幕上显示较大而在高密度屏幕上显示较小。这样的密度相关的大小的变化可能会致使应用程序的布局和可用性问题。图2和图3显示了一个应用程序不提供密度独立性时的差别。


2. 应用程序不支持密度独立,在低,中,高密度屏幕上显示。


3. 应用程序支持密度独立,在低,中,高密度屏幕上显示,支持良好

Android系统能够经过两种方式使应用程序实现密度独立:

  • 系统缩放dp单位以适应当前屏幕密度

  • 系统基于当前屏幕密度按须要缩放可曳资源到合适尺寸

在图2中,text view和bitmap以像素为单位指定尺寸(像素单位),因此视图的物理尺寸在地密度屏幕上要大一些而在高密度屏幕上要小一些。这是由于实际的屏幕尺寸虽然多是相同的,具备高密度的屏幕每英寸的像素越多(相同数量的像素适合在一个较小的区域)。

在图3中,经过密度无关的像素(DP单位)指定布局尺寸。由于密度无关的像素的基线是一个中等密度的屏幕,一个中密度屏幕的设备看起来和图2中是同样的。然而,对低密度和高密度的屏幕,系统按比例调高或调低密度无关的像素值,分别以适应屏幕。

在大多数状况下,能够简单的经过用密度无关像素(dp units)来定义全部的布局尺寸或者适当的经过"wrap_content"来确保应用程序密度无关。而后系统依据当前屏幕密度的比例因子按比例决定bitmap drawable以显示合适的尺寸。

然而,位图缩放可能会致使模糊或像素化的位图。为了不这些人为效果,应该为不一样密度提供选择性位图资源。例如,应该为高密度的屏幕提供更高分辨率的位图从而系统能够没必要去调整为低密度屏幕准备的位图。如下部分描述如何为不一样的屏幕配置提供选择性资源。

如何支持多屏幕

Android能够为当前的屏幕配置经过适当的方式管理应用程序的layout和bitmap drawables的表现,这种能力是Android支持多屏幕的基础。系统处理的应用程序屏幕适配的大部分工做,尽管如此,为了更妥善处理不一样的屏幕配置,应该注意如下几点:

  • 在清单文件中明确声明应用程序支持的全部屏幕尺寸

经过声明应用程序支持的屏幕尺寸,能够保证只有那些屏幕尺寸被应用程序支持的设备才能够下载该应用程序。声明对不一样屏幕尺寸的支持,也能够影响系统如何在更大的屏幕展示应用程序特别地,应用程序是否在屏幕兼容模式运行。声明应用程序支持的屏幕尺寸,应该在manifest文件中包括 <supports-screens>元素。

  • 为不一样的屏幕尺寸提供不一样的布局

默认状况下,Android从新调整应用程序的布局,以适应当前的设备屏幕。在大多数状况下,这工做得很好。在其余状况下,用户界面可能看起来不太好,可能须要为不一样屏幕尺寸的做调整。例如,在大屏幕上,可能要调整某些元素的位置和大小,充分利用额外的屏幕空间,或在一个较小的屏幕上,可能须要调整大小,让全部元素均可以在屏幕上显示。可使用限定符来提供尺寸相关的资源,这些限定符包括smallnormallarge,  xlarge。例如,一个超大大屏幕的布局,应该在layout-xlarge/

从Android 3.2(API Level 13)开始,上述尺寸组已被弃用,应该使用sw<N>dp 限定符定义布局资源所需的最小可用宽度。例如,若是多窗格平板布局至少须要600dp屏幕的宽度,应该放置在layout-sw600dp/下。使用新技术来声明布局资源在 为Android 3.2设计平板布局部分有进一步讨论。

  • 为不一样的屏幕尺寸提供不一样的bitmap drawable

默认状况下,Android缩放bitmap drawables.png.jpg,.gif文件)和Nine-Patch drawables.9.png 文件),使它们在每台设备上呈现合适的物理尺寸。 

例如,若是应用程序只为基准,中型屏幕密度(MDPI)屏幕提供了bitmap drawable,那么系统将会在高密度屏幕上放大它们,而在低密度屏幕上缩小它们。这种缩放可能会让位图产生失真。 

为了让位图最好的展现,应该为不一样屏幕密度提供不一样分辨率的位图。

可使用限定符来提供密度相关的资源,这些限定符包括ldpi (low), mdpi (medium), hdpi (high),  xhdpi (extra high)。例如,为高密度屏幕提供的位图应该放在drawable-hdpi/下。

与广义的尺寸和密度相对应的尺寸和密度限定符在上文的屏幕支持范围中有描述。

: 若是不熟悉配置限定符和系统如何使用它们来请求选择性资源,阅读Providing Alternative Resources获取更多信息。

在运行时,系统为任何给定资源经过如下步骤来尽量确保它们在当前屏幕的显示:

  1. 系统使用适当的可选资源

当前屏幕的大小和密度的基础上,系统使用应用程序提供的任意尺寸和密度相关资源。例如,设备有一个高密度的屏幕而且应用程序请求一个drawable 资源,系统会寻找一个最匹配设备配置的drawable 资源目录。与其它可选资源相比,以hdpi 为限定符的资源目录(好比drawable-hdpi/)会最佳匹配,因此系统使用该目录下的drawable资源。

  1. 若是没有匹配的资源是可用的,系统将使用默认的资源而且对其进行缩放来适应当前的屏幕尺寸和密度。 

“默认”的资源是那些没有配置限定符的资源。例如,在drawable/ 下的就是是默认的资源。系统假定默认资源是为基线屏幕尺寸和密度而设计的。正由于如此,系统对其采起缩放是比较可取的。

然而,当系统试图寻找一个密度相关的资源可是在密度相关的目录下没有找到时,系统并不老是使用默认资源。系统可能会改用其余密度相关的资源之一,以提供更好的缩放结果。 例如,当寻找一个低密度资源而没找到时,系统倾向于缩小高密度资源,由于系统能够经过缩放因子0.5轻松地将高密度资源缩小为低密度,这种缩放要比经过缩放因子0.75将中密度资源缩小为低密度不易失真。

更多信息请参阅How Android Finds the Best-matching Resource

使用配置限定符

Android支持多种配置限定符,来控制系统如何根据当前设备屏幕的特色选择可选的资源。配置限定符是一个字符串,能够在Android项目追加到资源目录,并指定配置资源的内部设计。

使用配置的限定符:

  1. 在工程的res/目录下建立一个新的目录,并将其以以下格式命名:<resources_name>-<qualifier>

    • <resources_name> 是标准的资源名 (好比drawable 或者 layout).

    • <qualifier> 是一个配置限定符, 以下面的表1所示, 它限定了这些资源能够用于的屏幕配置(好比 hdpi 或者 xlarge).

能够一次使用多个 <qualifier> —使用破折号将多个限定符分开。

    • 在这个新目录保存适当的配置相关资源。资源文件命名务必与默认的资源文件命名一致。

好比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.

注:对于Android 3.2以及以上版本,请参阅 为Android 3.2设计平板布局获取关于新的配置限定符的更多信息(不要使用表1中的尺寸限定符)

欲了解更多有关如何将这些限定符与实际的屏幕尺寸和密度相对应的信息,请看本文档前面的屏幕支持范围

例如,下面是一个应用程序的资源列表,它为不一样的屏幕尺寸提供不一样的布局,而且为中,高,超高密度的屏幕提供不一样的bitmap drawable

res/layout/my_layout.xml    // layout for normal screen size ("default")
res
/layout-small/my_layout.xml       // layout for small screen size
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/my_icon.png        // bitmap for medium density
res
/drawable-hdpi/my_icon.png        // bitmap for high density
res
/drawable-xhdpi/my_icon.png       // bitmap for extra high density

欲了解更多有关如何使用选择性资源和配置限定符的完整列表(不仅是屏幕配置)的信息,请参阅Providing Alternative Resources

注意,Android系统在运行时选择使用哪些资源时,它使用某些逻辑来决定“最佳匹配”的资源。也就是说,使用的限定符没有必要彻底匹配当前的屏幕配置。具体来讲,当基于尺寸限定符来选择资源时,若是没有更好的匹配,系统会选择使用为比当前屏幕小的屏幕设计的资源(例如,一个大屏若是须要,可能会使用正常屏的资源)。可是,若是只有比当前屏幕尺寸大的资源,那么系统将不会使用这些大的资源,应用程序将会因无从选择而崩溃。(例如,若是全部的资源都是xlarge 限定符的,可是设备是一个normal-size的设备)。

更多关于系统如何选择资源的信息,请参阅 How Android Finds the Best-matching Resource

提示:若是有一些绘制资源,不想让系统进行缩放(也许是由于想要在程序运行时进行手动调整),应该将其放置nodpi 配置限定符的目录下。这个限定符的资源被视为密度无关,系统将不能扩展。

设计选择性的布局和图片

替代资源的类型,取决于应用程序的需求。一般,应该使用尺寸和方向限定符提供选择性的布局资源,使用密度限定符提供选择性的图片资源。如下部分分别归纳了该如何使用尺寸和密度限定符提供选择性的布局和图片。

选择性的布局

应该确保应用程序的布局:

  • 适合在小屏幕上(确保能够实际使用)

  • 在大屏幕上,确保充分利用额外的屏幕空间

  • 适应竖屏和横屏

若是用户界面,须要让位图来适应视图的大小(如一个按钮的背景图片),应该使用Nine-Patch 位图文件。Nine-Patch文件基本上是一个PNG文件它能够在特定的二维地区伸展。当系统须要拉伸位图所在的视图时,系统会拉伸Nine-Patch文件,可是仅仅拉伸的是指定区域。正由于如此,不须要提供不一样的屏幕尺寸不一样的图片,由于Nine-Patch的位图,能够调整到任何尺寸。然而,应该为不一样的屏幕密提供不一样的Nine-Patch文件。

选择性的图片


Figure 4. 支持各密度的位图的相对大小

几乎每一个应用程序都应当为不一样的屏幕密度提供图片资源,由于几乎每个应用程序都拥有一个启动图标,而改图标应当在不一样密度的屏幕上显示良好。

: 只需提供密度相关的位图文件(.png.jpg, 或者 .gif) Nine-Path 文件(.9.png)。若是须要使用XML来定义形状,颜色或者可绘制的资源,应当在默认的drawable 目录备份一份。

要建立不一样密度的选择性的图片,应该在四个广义密度之间遵循3:4:6:8的缩放比例。好比,一个中密度下为48x48像素的位图(应用程序启动图标),与之对应的全部不一样的尺寸应当是:

  • 低密度为36x36 

  • 中密度为48x48 

  • 高密度为72x72 

  • 超高密度为96x96 

更多关于设计图标的信息,请参阅 Icon Design Guidelines它涵盖了各类位图的尺寸信息,好比启动图标,菜单图标,状态栏图标,tab 图标等等。

Android 3.2设计平板布局

对于第一代运行Android 3.0的平板电脑来讲,声明平板布局的适合方式是使用xlarge 限定符(好比res/layout-xlarge/)。为了适应其余类型的平板电脑和屏幕尺寸,Android 3.2引入了一种新的为分散屏幕尺寸定义资源的方式。这种新技术是基于布局所需的空间数量(好比600dp宽),而不是试图让布局去符合广义的尺寸分类(好比大或者超大)。

使用新的尺寸限定符

见表2,这些新的限定符,比传统的屏幕尺寸分类(小,中,大,和超大)能提供更多的对于定义应用程序支持的屏幕的控制。

: 使用这些限定符指定的大小不是实际的屏幕尺寸。相反,是能够用于活动窗口的宽度或者高度尺寸,是以dp为单位的。系统会为系统UI使用一些屏幕空间(好比系统栏或者状态栏),因此一些屏幕空间对应用程序是不可用的。所以,声明的尺寸应当明确的是activity所需的尺寸当系统声明应当提供多少空间给布局时,它会计算任何被系统UI占据的空间。 同时注意, Action Bar被认为是应用程序的一部分空间,尽管布局没有声明它,所以它减小了可用的布局空间,你必须考虑在设计以内。

Table 2. 屏幕尺寸的新的配置限定符(在Android 3.2中引入)

Screen configuration

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 of available screen is at least 600dp, regardless of whether the 600dp side is the user-perceived height or width. The smallestWidth is a fixed screen size characteristic of the device; the device's smallestWidth does not change when the screen's orientation changes.

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 be smaller than the actual screen size, because those are screen pixels not available for your UI.

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 width is often the driving factor in designing a layout. A UI will often scroll vertically, but have fairly hard constraints on the minimum space it needs horizontally. The available width is also the key factor in determining whether to use a one-pane layout for handsets or multi-pane layout for tablets. Thus, you likely care most about what the smallest possible width will be on each device.

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 for the layout, instead of using both the screen size and orientation qualifiers together.

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 UIs often scroll vertically and are thus more flexible with how much height is available, whereas the width is more rigid.

虽然使用这些限定符可能看起来比使用屏幕尺寸分组彷佛更复杂,一旦肯定用户界面的要求,它实际上应该是更简单。当设计UI时,关心的主要事情是当应用程序在手机式UI和平板式UI之间迁移时它的实际尺寸。

更多关于尺寸配置限定符的讨论,请参阅Providing Resources

配置实例

为了您针对不一样类型的设备进行设计,这里是典型的屏幕宽度的一些数字:

  • 320dp: 一个典型的手机屏幕 (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, ).

  • 480dp: Streak同样的中立平板屏幕 (480x800 mdpi).

  • 600dp: 7”平板 (600x1024 mdpi).

  • 720dp: 10”平板 (720x1280 mdpi, 800x1280 mdpi, ).

使用表2中的尺寸限定符,应用程序可使用任何您想要的宽度和/或高度为手机和平板之间切换不一样的布局资源。好比,若是600dp是平板布局所支持的最小可用宽度,能够提供这两套布局:

res/layout/main_activity.xml           # For handsets
res
/layout-sw600dp/main_activity.xml   # For tablets

在这种状况下,为了让平板布局实用,可用屏幕空间的最小宽度必须为600dp。 

要进一步定制UI区分大小,如7“和10”平板的状况下,能够定义额外的最小宽度布局:

res/layout/main_activity.xml           # For handsets (smaller than 600dp available width)
res
/layout-sw600dp/main_activity.xml   # For 7” tablets (600dp wide and bigger)
res
/layout-sw720dp/main_activity.xml   # For 10” tablets (720dp wide and bigger)

注意,前面的两个例子资源使用“最小宽度”限定符,sw<N>dp,它指定屏幕两边的最小值,不管设备的当前方向。所以,使用sw<N>dp是简单的经过忽略屏幕方向的方式来指定布局的总体屏幕尺寸。

然而,在某些状况下,可能重要的是布局究竟有多大的宽度或高度目前是可用的。例如,有两个并排的布局,每当屏幕宽度至少提供600dp时使用,不论设备是不是在横向或纵向。在这种状况下,资源看起来像这样:

res/layout/main_activity.xml         # For handsets (smaller than 600dp available width)
res
/layout-w600dp/main_activity.xml  # Multi-pane (any screen with 600dp available width or more)

请注意,第二组使用“可用宽度”限定符,w<N>dp。这样,一台设备可能根据屏幕的方向会使用这两种布局(若是可用宽度在一个方向至少600dp而在另外一个方向小于600dp)。

若是关注的是可用高度,那么一样可使用h<N>dp限定符。甚至能够结合使用w<N>dp  h<N>dp 限定符。

声明屏幕尺寸支持

一旦已经为不一样的屏幕尺寸实现了布局,一样重要的是在应用程序的manifest文件中声明应用程序支持哪些屏幕。

随着屏幕尺寸的新的配置限定符,Android 3.2引入了<supports-screens> 元素的新属性。

android:requiresSmallestWidthDp

指定的最低宽度。 smallestWidth是指必须提供给应用程序的UI最短尺寸的屏幕空间(单位dp),也就是说,最短的可用屏幕的两个维度。所以,为了让一个设备与应用程序兼容,设备的smallestWidth必须等于或大于这个值。 (一般状况下,该值是布局支持测“最小宽度”,不管当前屏幕的方向。)

例如,若是应用程序仅用于最小可用宽度是600dp的平板式设备:

<manifest ... >
   
<supports-screens android:requiresSmallestWidthDp="600" />
    ...
</manifest>

不过,若是应用程序支持Android支持的全部屏幕尺寸(如426dp x 320dp这么小),那么并不须要声明这个属性,由于应用程序须要的最小宽度在任何设备上都是最小的。

注意:Android系统并不关注这个属性,因此它不会影响应用程序在运行时的行为。相反,它被用于过滤应用程序,如Google Play(谷歌播放)。然而,目前谷歌播放不支持过滤(基于Android 3.2)这个属性,因此若是应用程序不支持小屏幕,应该继续使用其余的大小属性。

android:compatibleWidthLimitDp

这个属性容许经过指定应用程序支持的最大"smallest width"来让screen compatibility mode (屏幕兼容模式)成为用户可选的特性。若是设备的可用屏幕最小的一边大于该值,用户仍然能够安装该应用程序,但提供在屏幕兼容性模式运行。默认状况下,屏幕兼容模式是无效的,并且布局会去调整适应普通的屏幕,可是系统栏会提供一个按钮来容许用户切换屏幕兼容模式开关。

注:若是应用程序的布局适当调整以适应大屏幕,则不须要使用这个属性。建议避免使用这个属性,而应当按照本文的建议确保布局调整以适应大屏幕。

android:largestWidthLimitDp

这个属性容许经过指定应用程序支持的最大的"smallest width"来强制启用 screen compatibility mode屏幕兼容模式。若是设备的可用屏幕最小的一边大于该值,应用程序会强制运行在屏幕兼容模式,用户没法干预。

注:若是应用程序的布局适当调整以适应大屏幕,则不须要使用这个属性。建议避免使用这个属性,而应当按照本文的建议确保布局调整以适应大屏幕。

注意:为Android 3.2及以上版本开发时,不该该使用上面列出的属性结合旧的屏幕大小属性。同时使用新属性和旧属性,可能会致使意想不到的行为。

最佳实践

支持多屏幕的目标是建立一个应用程序能够正常而且很好地运行在Android支持的任何的广义屏配置。前几节提供有关Android是如何适应应用程序的屏幕配置,以及如何自定义应用程序在不一样的屏幕配置上的展示。本节提供了一些额外的技巧和技术的概述,以帮助确保应用程序适配不一样的屏幕配置。

这里是一个有关如何能够确保应用程序在不一样的屏幕上正确显示的快速清单:

  1. 当在XML布局文件中定义尺码时,使用 wrap_contentfill_parent, 或者 dp 单位 

  2. 不要在应用程序代码中使用硬编码的像素值

  3. 不要使用 AbsoluteLayout (它已被废弃)

  4. 为不一样的屏幕密度提供可选的位图

如下部分提供更多细节。

1.当在XML布局文件中定义尺码时,使用 wrap_content, fill_parent, 或者 dp 单位

当为XML布局文件定义android:layout_width  android:layout_height时,使用"wrap_content""fill_parent" 或者 dp单位,能够确保视图在当前屏幕上有一个合适的尺寸。

例如,一个layout_width="100dp"的视图在中密度屏上占用100像素,而在高密度屏上则是150像素,因此视图在屏幕上占用大约相近的物理空间。

一样,应该更倾向于使用sp scale-independent pixel)来定义文本大小。 sp 缩放因子和dp.同样取决于用户设置和系统缩放的大小。

2.不要在应用程序代码中使用硬编码的像素值

不做过多解释。

若是应用程序操纵位图或在运行时的像素值,请参阅Additional Density Considerations

3. 不要使用 AbsoluteLayout

不一样于其余布局部件,AbsoluteLayout强制使用固定的位置去摆放子视图,这很容易致使在不一样的显示器的用户界面不能好好工做。 正由于如此,AbsoluteLayout在Android 1.5(API等级3)被废弃。

应该使用RelativeLayout,它使用相对定位来摆放子视图。例如,能够指定一个按钮部件让它显示在文本部件的右侧。

4. 使用基于尺寸和密度的资源

若是想严格控制应用程序在不一样屏幕配置上的展现,那就在配置相关的资源目录下调整布局和图片。例如,考虑到想要在中等和高密度显示屏上用到的图标,只需建立两个大小不一样(例如中密度的为100x100,高密度的为150X150)的图标,并使用适当的限定放置在相应目录下:

res/drawable-mdpi/icon.png   //for medium-density screens
res
/drawable-hdpi/icon.png   //for high-density screens

注:若是目录名中没有定义密度限定符,系统假定该目录中的资源为基准密度而设计,并会为其余密度做适当扩展。

更多关于配置限定符的信息,请参阅使用配置限定符

关于密度的额外思考

本节将介绍更多的Android在不一样的屏幕密度上如何处理位图的缩放,以及如何能够进一步控制位图在不一样屏幕密度上的绘制。本节信息对于大多数的应用程序是不重要的,除非在不一样屏幕密度上运行应用程序时遇到问题或者应用程序须要操做图像。

为了更好地了解如何在运行时操做图像时支持多密度,应该了解,系统有助于确保位图的适当缩放,表如今如下方面:

  1. 预缩放资源 (好比 bitmap drawables)

基于当前屏幕的密度,系统不加缩放地使用应用程序的任何尺寸或密度相关资源。若是资源不是以正确的密度提供的,系统会加载默认的资源而且按须要根据当前屏幕密度进行缩放。系统假定默认资源(那些在没有配置限定符的目录下的资源)是为基准屏幕密度(mdpi)设计的,除非他们是从一个特定密度的资源目录加载。所以,预缩放就是系统为当前屏幕密度进行适当的缩放资源。

若是请求预缩放资源的尺寸,系统将返回缩放后的尺寸。例如位图,为mdpi屏幕设计的50 x50像素的位图在hdpi的屏幕上被放大到75x75像素,那么系统报告的就是75x75像素。

有一些状况下,可能但愿Android不进行预缩放。避免预缩放的最简单的方法,就是把资源放在以nodpi 配置限定符标识的目录下,好比:

res/drawable-nodpi/icon.png

这样,当系统选用该文件夹的icon.png位图时,不会基于当前屏幕密度进行扩展。

  1. 像素尺寸和坐标的自动缩放

应用程序能够经过在manifest中设置android:anyDensity 为“false”或者在程序中设置BitmapinScaled"false"这种来禁用预缩放。在这种状况下,系统在绘制时自动调整任何绝对的像素坐标和像素尺寸值。它这样作,以确保像素定义屏幕元素仍然与在基准屏幕密度(mdpi)下显示相近的物理尺寸。系统为应用程序透明的处理这个比例而且报告缩放过的像素给应用程序,而不是物理像素尺寸。 

一般状况下,不该该禁用预缩放。支持多个屏幕的最好办法是上文提到的如何支持多屏幕

若是应用程序操纵位图,或以一些其余的方式与屏幕上的像素进行直接交互,可能须要采起额外的步骤,以支持不一样的屏幕密度。例如,若是经过计算手机通过的像素数来响应触摸手势,则须要使用适当的密度无关的像素值,而不是实际像素。

在运行时建立的缩放位图对象


Figure 5. 预缩放和自动缩放位图的比较, 来自 ApiDemos.

若是应用程序建立一个内存位图(Bitmap 对象),系统会假设该位图是专为基准密度屏幕设计的而且在绘制时进行自动缩放。系统当位图有不明密度属性时,将 “自动缩放”运用于一个Bitmap位图。若是没有正确地统计当前设备的屏幕密度,并指定位图的密度属性,自动缩放会致使缩放失真,就像没有提供可选性资源同样。

为了控制在运行时建立的位图是否被缩放,能够用setDensity()来指定位图的密度,经过传递一个来自DisplayMetrics的密度常量,好比DENSITY_HIGH 或者 DENSITY_LOW

若是使用BitmapFactory建立一个Bitmap ,如从一个文件或流,可使用BitmapFactory.Options来定义位图属性,该属性决定了系统是否或者如何缩放位图。

图5演示了预缩放和自动缩放在高密度屏上加载低(120),中(160)和高(240)密度位图的结果。差别是微妙的,由于全部位图被缩放以匹配当前屏幕密度,可是缩放的位图呈现细微的区别,这取决于它们在绘制时时预缩放的仍是自动缩放的。能够在ApiDemos代码中找到这个示例应用程序,它演示了如何使用预缩放和自动缩放位图。

: 在Android 3.0及以上版本,因为在图形架构的改进,预缩放和自动缩放位图之间没有可感知的差别, 

dp单位转换为像素单位

在某些状况下,须要用dp 来表示尺寸,而后将它们转换为像素。想象一个应用程序,当用户手指移动至少16像素,则造成一个滚动或者抛掷手势。在基准屏幕上,用户必须在手势造成以前移动16个像素/ 160 dpi,等于一英寸的十分之一(2.5毫米)。在高密度显示器(240dpi)的设备上,用户必须移动16个像素/ 240 dpi,这等于一英寸的十五分之一(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;在一个高密度的屏幕上,它等于1.5;在一个超高密度屏幕上,它等于2.0;在低密度屏幕上,它等于0.75。用dp乘以这个数字就获得当前屏幕的实际像素数值。 (当转换为整数时,添加0.5f 四舍五入到最接近的整数)。有关详细信息,请参阅的DisplayMetrics类。

然而,对这类事件,应该使用 ViewConfiguration预缩放的配置值,而不是定义一个任意的门槛。

使用预缩放的配置值

可使用ViewConfiguration 类访问Android系统的通常的的距离,速度和时间。例如,能够经过getScaledTouchSlop()得到框架使用的滚动门槛;

private static final int GESTURE_THRESHOLD_DP = ViewConfiguration.get(myContext).getScaledTouchSlop();

ViewConfiguration 类中以getScaled 为前缀的方法能够保证返回能够正确显示的像素值,不论当前的屏幕密度。

如何在多屏幕上测试应用程序


Figure 6. 用来测试屏幕支持的一组AVD。

发布应用程序以前,应该在全部支持的屏幕尺寸和密度上进行完全的测试。 Android SDK中包含可使用的模拟器皮肤,它复制常见的屏幕配置的大小和密度,应用程序可能运行于这些皮肤。也能够以任何特定的屏幕特色修改默认的大小,密度,和模拟器皮肤。使用模拟器的皮肤和额外的自定义配置,能够测试任何可能的屏幕配置,而不用买各类设备。 

为了搭建一个测试应用程序屏幕支持的环境,应该建立一系列AVD(Android虚拟设备),使用模拟器的外观和屏幕配置,模拟应用程序支持的屏幕尺寸和密度。这样作,可使用AVD管理器建立AVDS,而后使用图形界面启动它们。

启动Android SDK管理器,从Android SDK目录执行SDK Manager.exe 的(仅适用于Windows)或从<sdk>/tools/ 目录执行android (全部平台)。图6显示了AVD管理器中的一组AVD。

表3显示了Android SDK中的各类仿真皮肤,能够用它来模拟一些最多见的屏幕配置。

欲了解更多有关建立和使用的AVD来测试应用的详细信息,请参阅Managing AVDs with AVD Manager

Table 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)
1024x768
1280x768

1536x1152
1920x1152 
1920x1200

2048x1536
2560x1536 
2560x1600






查看支持任何屏幕配置的活动设备的相关数值,请参阅Screen Sizes and Densities


Figure 7. 当从AVD管理器启动AVD时,能够设置的尺寸和密度选项

还建议在这样的模拟器上去测试应用程序,此模拟器被配置为物理尺寸和实际设备相近。这样作,须要电脑显示器的大概的DPI密度,(例如,30“戴尔显示器具备大约96 dpi的密度)。当从AVD管理器启动一个AVD时,能够在Launch Options中为模拟器和监视器指定dpi,如图7所示。

若是想要在一个不被内置皮肤所支持的分辨率或者密度的屏幕上测试应用程序,能够用自定义的分辨率和密度建立一个AVD。当从AVD管理器建立一个AVD时,定义分辨率,而不是选择内置皮肤。

若是从命令行启动AVD,可使用-scale例如选项来指定模拟器规模。例如:

emulator -avd <avd_name> -scale 96dpi

为了细化模拟器的尺寸,能够替代-scale选项为一个0.1到3之间的数字,它表明指望的缩放因子。


注:本文译自android开发者网站,原文请参考http://developer.android.com/guide/practices/screens_support.html

相关文章
相关标签/搜索