- Android开发权威指南(第二版)
- 李宁编著
- 426字
- 2024-12-21 14:46:29
12.5 屏幕适配
尽管12.1节的表12-1已经列出了Android最新版支持的所有配置标识符,但各种标识符错综复杂,初学者可能会被立刻搞晕。不知道什么时候该用哪些标识符进行本地化。当然,对于有些配置标识符并不复杂,例如,语言、地区、Android版本等。不过对于与屏幕适配相关的配置标识符却显得太复杂,这些标识符占了整个标识符的一半左右,而且有很多标识符互相重叠,所以灵活运用这些标识符的确不是一件容易的事。因此,就算Android支持众多的配置标识符,要想让一个Android应用支持尽可能多的屏幕尺寸、屏幕密度也不是一件容易的事。为了使读者可以更深入理解屏幕适配的方法和原理,本章特意将这些与屏幕适配相关的标识符单独提出来讲解,并且加入了很多屏幕适配的技巧。
本节介绍的方法要求API Level至少是4(Android 1.6),所以本节的内容并不适合Android 1.5及以前的版本。当然,目前仍然使用Android 1.5或更低版本的用户几乎已经绝迹了,所以开发Android应用时完全可以忽略Android 1.5及更低的版本。本节介绍的部分方法要求API Level至少是13(Android 3.2),这一点在介绍到相关内容时会指出。
12.5.1 屏幕适配要考虑的因素
Android程序员一定对“屏幕适配”这个词非常熟悉,因为在Android发展的数年时间里,屏幕适配曾经令无数程序员焦头烂额,当然,自从Apple推出iPhone 5后,Android程序员也因为熟悉屏幕适配的技巧而带来一丝自豪感。不过话又说回来,屏幕适配到底适配什么,应如何适配,可能很多Android程序员都能说出一二,但如果要深挖“屏幕适配”背后的故事,恐怕没有多少Android程序员能对此了如指掌。为了使广大的Android程序员可以对屏幕适配了解得更多,本节会着重介绍屏幕适配要考虑的多种要素,在随后的几节中会详细讨论各种屏幕适配技术。
屏幕适配主要考虑如下几点。
屏幕尺寸。
屏幕密度。
屏幕方向。
屏幕分辨率。
独立于屏幕密度的像素(dp)。
这些屏幕适配要素的详细介绍如下。
1.屏幕尺寸
屏幕实际的物理尺寸,也就是屏幕对角线的长度。为了方便,Android将各种屏幕物理尺寸分为如下4种。
small。
normal。
large。
extra large。
2.屏幕密度
屏幕每英寸包含的物理像素点个数,通常使用dpi(dots per inch,每英寸像素点个数)表示。例如,中密度的屏幕会比高密度的屏幕每英寸包含的像素点更少,因此屏幕在显示画面时没有高密度屏幕细腻(图像的效果更明显)。
为了方便,Android将多种实际的屏幕密度分为如下4种。
低密度(low density)。
中密度(medium density)。
高密度(high density)。
扩展高密度(extra high density)。
从Android 3.2(API Level = 13)开始又增加了一种用于智能电视的TV密度(tvdpi)。
3.屏幕方向
自从传感器引入手机以来,手机通过方向传感器可以实现界面在2个到4个方向上的旋转。这就要求程序界面支持横屏(landcape)和纵屏(portrait)的布局。适应这两种布局的通常做法是提供两个不同的布局资源文件。不过也可以在运行时感知屏幕方向的变化,并及时调整屏幕的布局。
4.屏幕分辨率
整个屏幕的物理像素个数,通常用N*M表示,N表示横向分辨率、M表示纵向分辨率,例如,480*800、600*1024等。在早期的Android版本中曾支持直接使用屏幕分辨率的配置标识符,不过在高版本的Android中已经不允许直接使用屏幕分辨率作为配置标识符了。通常会使用屏幕尺寸和屏幕密度来近似表示屏幕分辨率,也就是说一组近似的分辨率会对应同一个屏幕尺寸或屏幕密度。
5.独立于屏幕密度的像素(dp)
dp是与屏幕密度无关的单位,通常用于设置UI布局的位置和尺寸。dp相当于160dpi屏幕的物理像素,也就是说,如果当前屏幕是中密度,那么dp与px(像素)等效。如果当前屏幕不是中密度,系统会使用如下的公式计算出实际的物理像素,以使UI的相对位置和尺寸在不同密度的屏幕上保持不变。
px = dp * (dpi / 160)
其中dpi表示当前屏幕的密度。例如,当前的TextView控件的宽度设为160dp,程序运行在高密度屏幕的手机上,dpi为240(每英寸240个物理像素),那么TextView控件的实际物理像素是240px,计算方法如下:
px = 160 * (240 / 160) = 240
从这一点可以看出,在高密度屏幕下,1dp = 1.5px,而在低密度(每英寸120个物理像素)屏幕下,4dp = 3px。
12.5.2 适配不同屏幕可以采用的规则
在上一小节介绍了适配屏幕要考虑的因素,这一小节来看看对于适配各种类型的屏幕可以采用哪些规则。然后在随后的几节中会详细介绍这些规则的使用方法。
适配屏幕通常可以采用指定程序支持的屏幕尺寸,为不同尺寸、密度的屏幕提供不同的布局以及图像。这些方法尽管看上去很简单,但其中却蕴含者很多玄机,下面就一一道来。
1.限制屏幕尺寸
如果应用程序是专门为某类屏幕设计的,例如,large等级的屏幕,最简单的方法就是直接在AndroidManifest.xml文件中通过<compatible-screens>或<supports-screens>标签限制屏幕尺寸。通过这两个标签可以使不满足屏幕要求的手机在Google Play上无法找到你的程序。
2.为不同的屏幕尺寸提供不同的布局
通常情况下Android会自动调整界面的布局,例如,如果一个按钮位于屏幕顶端的中心位置,当屏幕旋转后,该按钮仍然会在屏幕顶端的中心位置。这种调整方式大多数情况下运行良好,但在某些特殊情况下,不同屏幕尺寸或屏幕的横竖屏,UI的布局可能有很大差异,甚至完全不同,这就要求为每一种屏幕尺寸单独设计布局。
这些布局会放到相应的本地化布局资源目录中,在Android 3.2以前的版本中,可以考虑屏幕尺寸和屏幕密度。例如,屏幕尺寸分为4个等级:small、normal、large和xlarge。如果为这4个尺寸等级都提供相应的布局资源,就需要建立4个布局资源目录:res/layout-small、res/layout-normal、res/layout-large和res/layout-xlarge。
从Android 3.2(API Level = 13)开始,新增加了3个配置标识符:屏幕的最小宽度、可使用屏幕宽度和可使用屏幕高度。例如,屏幕的最小宽度使用sw<N>dp表示,其中N表示最小宽度值,如果要为屏幕最小宽度是600dp的Android设备提供布局文件,需要将布局文件放到res/layout-sw600dp目录中。
3.为不同屏幕的密度提供不同分辨率的图像
默认情况下,Android会拉伸普通图像(.png, .jpg和 .gif 文件)和Nine-Patch图像,但对于不同屏幕密度来说,图像的拉伸可能会造成失真。因此,对于那些色彩比较丰富的图像,通常会为每一种屏幕密度单独提供相应分辨率的图像。目前Android将屏幕密度分为4个等级:ldpi(低密度)、mdpi(中密度)、hdpi(高密度)和xhdpi(扩展高密度)。例如,如果要分别为高密度和中密度屏幕提供图像资源,就要建立res/drawable-mdpi和res/drawable-hdpi两个本地化图像资源目录。
通常情况下,如果系统未发现相应屏幕配置的资源目录,就使用默认的资源目录,但有时系统也会寻找更合适的其他屏幕配置的资源目录。例如,如果当前屏幕为中密度,当程序并未提供res/drawable-mdpi目录时,按通常做法,系统会在res/drawable目录中寻找相应的图像资源。但有时系统也会选择res/drawable-hdpi目录中的图像资源,因为对分辨率高的图像压缩尺寸通常要比对分辨率低的图像放大尺寸效果要好。
12.5.3 屏幕尺寸和屏幕密度
从Android 1.6(API Level = 4)开始,Android开始支持多屏幕尺寸和屏幕密度适配,通过这种适配方式,可以覆盖目前所有的屏幕配置(不再需要像以前那样直接指定屏幕物理分辨率了)。
为了简化设计用户接口的过程,Android对各种屏幕配置进行了泛化,将屏幕适配划分成屏幕尺寸和屏幕密度。
屏幕尺寸分为4个等级:small、normal、large和xlarge。不过从Android 3.2(API Level= 13)开始,屏幕尺寸已不建议使用,取而代之的是最小屏幕宽度、可使用的屏幕宽度和高度。但如果要开发Android 3.2以前版本的,仍需要使用屏幕尺寸。
屏幕密度分为4个等级:ldpi(低密度)、mdpi(中密度)、hdpi(高密度)和xhdpi(扩展高密度)。
屏幕尺寸和屏幕密度分别以normal和mdpi为基准,这是因为Android的第一部手机T-Mobile G1就是HVGA屏幕,屏幕尺寸和屏幕密度分别为normal和mdpi。在Android 1.6以前,normal和mdpi仍然是Android唯一支持的屏幕配置。
每一个屏幕尺寸和屏幕密度都对应于一个范围,而不是一个固定的值,也就是说尽管多部设备的屏幕尺寸都属于normal,但它们的屏幕物理尺寸和长宽比例可能不同。例如,笔者曾经使用过HTC G3和Dell mini3,这两个型号的手机的屏幕都属于normal。但G3的屏幕物理分辨率是320*480,而mini3的屏幕物理分辨率是320*640。很明显,G3和mini3的屏幕尺寸和长宽比并不相同,但它们的屏幕尺寸却都属于normal。图12-2是泛化的屏幕尺寸、屏幕密度与实际的屏幕尺寸、屏幕密度的对应关系。
▲图12-2 泛化的屏幕尺寸、屏幕密度与实际的屏幕尺寸、屏幕密度的对应关系
使用屏幕尺寸设计UI时,必须要了解每一种屏幕尺寸要求的最小屏幕长宽尺寸。这些最小长宽尺寸使用dp(与屏幕密度无关的像素)作为单位。下面是上述4种泛化的屏幕尺寸对应的最小屏幕长宽尺寸。
xlarge:960dp720dp。
large:640dp480dp。
normal:470dp320dp。
small:426dp320dp。
这些尺寸的单位都是dp,这就意味着与其对应的屏幕物理像素除了与屏幕尺寸有关,还与屏幕密度有关。例如,如果屏幕为中密度,dp与px等价,所以任何470px <= h < 640px、320px <= w <480px的屏幕(h和w分别表示屏幕高度和宽度)都属于normal。而对于高密度屏幕,由于1dp=1.5px,所以large要求的最小物理尺寸是960px720px。
现在以Nexus 7和Nexus S为例,解释一下Android系统如何计算某一个型号的设备属于哪类屏幕尺寸。Nexus 7的屏幕密度是213(每英寸有213个物理像素点),为了方便,直接将屏幕的物理像素转换为dp,所以用dp为单位的屏幕尺寸为905dp553dp(Nexus 7的屏幕物理像素尺寸是1205736),对照上面4种泛化的屏幕尺寸,Nexus 7的屏幕尺寸属于large。对于Nexus S来说,屏幕密度为240(每英寸有240个物理像素点),而Nexus S的屏幕物理像素尺寸为800480,将其用dp表示是533dp320dp。从这一点可以看出,Nexus S的屏幕尺寸正好在normal与large之间,根据系统判定规则,这块屏幕属于normal。
注意
在Android 3.0以前的版本屏幕的最小尺寸定义不明确,因此可能会造成不同设备在normal和large等级判定上存在差异。例如,对于物理分辨率为1024720,并且是高密度的屏幕,如果将整个屏幕的尺寸都算在内,应该属于large等级,但如果只计算可用的区域(界面上可能有系统工具栏,这不算可用区域),那么屏幕尺寸可能会属于normal。不过从Android 3.0开始,屏幕尺寸的技术有明确的规则,也就是只计算可用区域,所以不会造成不同设备的判定结果不同的情况。
尽管屏幕尺寸和屏幕密度囊括了目前所有类型的屏幕,但通常并不需要为每一种屏幕尺寸和屏幕密度提供相应的本地化资源。大多数情况下可以使用与屏幕密度无关的像素单位dp,以及专门针对文字的sp来适应尽可能多的屏幕。
技巧点拨:如何得知当前设备的屏幕密度
前面曾多次提到和使用屏幕密度,例如,Nexus 7的屏幕密度是213、Nexus S的屏幕密度是240。那么这些值是怎么得到的呢?
当然,得到这些值的非技术方法是直接问生产厂商,不过这不在本书的讨论范围内。除了这种方法,还有很多技术手段来获取当前屏幕的尺寸和密度。
由于目前泛化的屏幕尺寸只有4种,所以最直接的方法就是建立4个值资源目录(values-small、values-normal、values-large和values-xlarge),并在这4个目录中建立一个XML文件(文件名可随意取值),然后分别在这4个文件中添加1个key相同,但值不同的字符串资源。
res/values-small/small.xml
<string name="size">small</string>
res/values-small/normal.xml
<string name="size">normal</string>
res/values-small/large.xml
<string name="size">large</string>
res/values-small/xlarge.xml
<string name="size">xlarge</string>
最后使用下面的代码输出size的值,如果输出了large,就说明当前屏幕的尺寸是large。
Log.d("screen_size", getResources().getString(R.string.size));
除了这种方法外,还有更直接方法。例如,通过下面的代码可以获取屏幕密度,屏幕的物理分辨率(物理像素尺寸)。
DisplayMetrics metrics = getResources().getDisplayMetrics();
// 获取屏幕密度,例如,在Nexus 7上返回213,在Nexus S上返回240
int density = metrics.densityDpi;
// 获取屏幕宽度的物理像素格式,例如,当Nexus 7横放的情况下,返回1280
int widthPixels = metrics.widthPixels;
// 获取屏幕高度的物理像素格式,例如,当Nexus 7横放的情况下,返回736
int heightPixels = metrics.heightPixels;
通过metrics.densityDpi / 160可以很容易算出物理像素尺寸与dp像素尺寸的比值,不过并不用这么麻烦,通过下面的代码可以直接获取这个比值。
// 获取当前屏幕密度与标准屏幕密度的比值,对于Nexus 7来说,也就是213/160 = 1.33
float densityScale= metrics.density;
// 与metrics.density基本相同,只是可能会根据具体的字体适当调整这个比值,因此该值主要应用与
// 文字的尺寸
float fontDensityScale = metrics.scaledDensity;
12.5.4 位置、尺寸和字体应使用屏幕密度单位
这个问题前面的章节已经多次提到,在本节再总结一下。如果想让UI尽可能适应各种屏幕密度和屏幕尺寸,位置和尺寸属性的单位应使用dp,而字体属性的单位应使用sp。当然,如果想让控件的尺寸(如TextView)随着控件中内容的变化而变化,可以将android:layout_width和android:layout_height属性值设为wrap_content。
图12-3是将Button和ImageView的尺寸属性设为px的效果,可以看到,在低密度、中密度和高密度3种屏幕上控件的尺寸依次递减,这是因为屏幕密度越高,每英寸包含的物理像素点越多,如果控件尺寸的像素点固定,自然就会产生屏幕密度越高,控件的尺寸越小了的情况。而图12-4由于使用了dp作为单位,系统会自动根据屏幕密度调整控件所占的物理像素,所以无论屏幕密度如何变化,只要屏幕尺寸不变,控件的尺寸看上去都一样。
▲图12-3 使用px的UI
▲图12-4 使用dp的UI
尽管各种UI都可以使用dp和sp来保存相对位置和尺寸不受屏幕密度的影响,但对于ImageView这样的控件,如果在高密度或扩展高密度屏幕上显示,尽管系统会自动调整ImageView控件占用的像素个数,但ImageView控件显示的图像本身的像素是固定的。如果ImageView控件占用的实际像素个数大于图像本身包含的像素个数,就意味着系统可能会拉伸图像(由ImageView控件的设置而定),这样就会造成图像的失真。因此,对于那些色彩比较丰富的图像,应为不同的屏幕密度提供对应的图像资源。例如,可以建立res/drawable-mdpi、res/drawable-hdpi等本地化图像资源目录。
12.5.5 与屏幕适配有关的标识符
在Android 3.2以前的版本,Android SDK提供了一些用于屏幕适配的配置标识符,这些配置标识符在12.1节的表12-1中已经介绍了,这里再来回顾一下。
屏幕尺寸(Screen Size):可用的标识符有small、normal、large、xlarge。
屏幕外观(Screen Aspect):可用的标识符有long、notlong。
屏幕方向(Screen Orientation):可用的标识符有port、land。
屏幕像素密度(Screen pixel density [dpi]):可用的标识符有ldpi、mdpi、hdpi、xhdpi、nodpi、tvdpi。
下面是一些使用这些配置标识符的本地化资源目录的例子。
res/layout/main_layout.xml // 用于normal屏幕尺寸的布局,也是默认的布局
res/layout-small/main_layout.xml // 用于small屏幕尺寸的布局
res/layout-large/main_layout.xml // 用于large屏幕尺寸的布局
res/layout-xlarge/main_layout.xml // 用于xlarge屏幕尺寸的布局
res/layout-xlarge-land/my_layout.xml // 用于xlarge屏幕尺寸,并且是landscape方向的布局
res/drawable-mdpi/icon.png // 用于中密度屏幕的图像
res/drawable-port-hdpi/icon.png // 用于高密度屏幕,并且屏幕方向是portrait的图像
res/drawable-xhdpi/icon.png // 用于扩展高密度屏幕的图像
从Android 3.2(API Level = 13)开始,又增加了几个用于屏幕适配的配置标识符,这些标识符设置的并不是屏幕的实际大小,而是屏幕可用区域以dp为单位的高度和宽度。通过这些新增加的配置标识符可以更容易地描述不同屏幕的尺寸和密度。
最小屏幕宽度(smallestWidth):标识符样式有sw<N>dp,例如sw320dp、sw600dp、sw720dp。
可使用的屏幕宽度(Available width)有标识符样式:w<N>dp,例如w720dp、w1024dp。
可使用的屏幕高度(Available height)有标识符样式:h<N>dp,例如h720dp、h1024dp。
12.5.6 影响屏幕适配的重要因素:布局和图像
布局和图像是屏幕适配过程中经常涉及的两种资源。
1.布局屏幕适配
布局可以使用与屏幕密度无关的单位(dp和sp)让UI自动调整,但在屏幕太小(如small等级的屏幕)或太大(如xlarge等级的屏幕)、以及屏幕方向变化的情况下,依靠系统自动调整会使有些控件过小或过大,明显降低用户体验和显示效果。因此,在这种情况下,建议单独提供相应的布局。
对于small等级的屏幕,由于屏幕尺寸太小,可能使用的UI布局与small和large等级的屏幕有很大差异。例如,由于缩小比例太大,Button会变得过小,上面的文字可能显示不下,这种情况下就需要单独为small等级的屏幕调整UI布局。
对于xlarge等级(有时large等级也有此情况)的屏幕,尽管通过布局自动调整后的界面在使用上没有什么问题,但各种控件的尺寸会明显增大,显得软件像刚毕业的实习生做的一样,用户会对软件的第一印象感觉很差,所以大多数情况下应为xlarge或large等级的屏幕专门提供UI布局。
当屏幕横竖屏切换时,屏幕会不断变宽(窄)变窄(宽)。在很多情况下,由于屏幕的高度或宽度突然变小,使得原来显示正合适的控件尺寸变小,甚至有一些控件无法显示了(被挤出了屏幕的可视范围),因此,如果在屏幕横向或纵向放置了大量的控件,除非这些控件的宽度或高度改变不影响用户体验,否则应为横屏和纵屏单独提供UI布局。
综上所述,除非控件的大小改变后不明显影响用户体验,否则应该为small、large、xlarge以及横纵屏单独提供UI布局。
2.图像屏幕适配
默认情况下,系统会根据屏幕的大小自动拉伸图像。对于普通图像(.png、.jpg或.gif)来说,整个图像都会被拉伸,而对于某些应用来说,只需要拉伸图像的一部分,例如,很多微博客户端都会将微博内容显示在一个上方带一个尖角的框中,这就需要在屏幕大小、方向改变后尖角永远保持不变。要想实现这样的功能,就需要使用Nine-Patch(.9.png)格式的图像(见10.6.3小节的介绍)。
如果图像拉伸的程度超过图像本身的尺寸,就会使图像失真,因此,在这种情况下需要为不同的屏幕密度(不需要考虑屏幕尺寸)单独提供相应分辨率的图像。
为不同密度的屏幕创建不同分辨率的图像资源时可以使用3:4:6:8的缩放原则。这4个数字是低密度(ldpi)、中密度(mdpi)、高密度(hdpi)和扩展高密度(xhdpi)对应的图像分辨率的比例。例如,Android应用在中密度屏幕上使用的图标(launcher icon)的分辨率是4848,那么这4个密度等级对应的图像分辨率如下:
3636:低密度。
4848:中密度。
7272:高密度。
9696:扩展高密度。
12.5.7 典型的屏幕适配案例
本节会给出一些典型屏幕适配的例子。为了帮助广大读者更好地进行屏幕适配,这里先给出一些典型的屏幕宽度。
320dp:典型的手机屏幕(如240320 ldpi、320480 mdpi、480800 hdpi等)。
480dp:手机和平板电脑都可能使用的尺寸(如480800 mdpi)。
600dp:用于7英寸的平板电脑(如Nexus 7的1280800,介于mdpi和hdpi之间)。
720dp::用于10英寸的平板电脑 (如Nexus 10的25601600,介于hdpi和xhdpi之间)。
如果使用表12-1所示的最小屏幕宽度,可以直接使用上面的值,例如,要为7英寸平板电脑和手机提供两个不同的布局文件(main_activity.xml),直接使用sw600dp即可。
res/layout/main_activity.xml //用于手机的布局文件
res/layout-sw600dp/main_activity.xml //用于7英寸平板电脑的布局文件
如果使用上面两个资源目录,只有屏幕可使用的宽度大于600dp时,系统才会使用res/layout-sw600dp目录中的资源,而通常只有7英寸或以上尺寸的平板电脑屏幕才能达到600dp。
如果还想更进一步区分屏幕的尺寸,例如,分别为手机、7英寸平板电脑和10英寸平板电脑提供布局文件,那么就需要在如下3个资源目录中分别放置相应的main_activity.xml文件。
// 用于手机的布局文件,屏幕最小宽度小于600dp
res/layout/main_activity.xml
// 用于7英寸平板电脑的布局文件,屏幕最小宽度大于等于600dp,但小于720dp
res/layout-sw600dp/main_activity.xml
// 用于10英寸平板电脑的布局文件,屏幕最小宽度大于等于720dp
res/layout-sw720dp/main_activity.xml
注意
如果只有res/layout-sw600dp资源目录,而没有res/layout-sw720dp资源目录,那么即使在10英寸或更大屏幕的平板电脑上运行,系统仍然会使用res/layout-sw600dp目录中的资源。也就是说只要屏幕的最小宽度大于等于600dp,就会从使用最接近自己最小屏幕宽度的本地化资源目录中的资源,如果没有这样的资源目录,就会到默认的资源目录寻找相应的资源,如果仍未找到,则会抛出异常。
当然,除了屏幕最小宽度,还可以通过可使用的屏幕高度和宽度进行屏幕适配,使用方法与屏幕最小宽度类似,详见表12-1。
12.5.8 在Google Play上限制屏幕尺寸和屏幕密度
尽管使用前面介绍的方式可以使同一个Android应用适合各种类型的屏幕,但最后发现,程序的结构变得越来越混乱,或处于其他原因决定为不同类型的屏幕单独开发相应的版本,这就需要在AndroidManifest.xml文件中通过<compatible-screens>标签进行设置,在Android 3.2及以后的版本中,还可以使用<supports-screens>标签进行设置。通过这两个标签可以指定当前的程序支持的屏幕尺寸、屏幕密度、屏幕最小宽度等信息。如果将该程序发布到Google Play等软件商店,会根据当前浏览软件商店的Android设备显示适合于当前屏幕的Android应用。例如,如果限定当前的Android应用只支持7英寸和10英寸平板电脑,那么使用手机浏览Google Play时是看不到这个Android应用的。
注意
<compatible-screens>和<supports-screens>标签只能通过软件商店(如Google Play)将不适合当前Android设备屏幕的Android应用隐藏起来,并不能阻止Android应用在不合适的屏幕上运行。例如,只适合7英寸平板电脑的Android应用同样也可以安装在手机上(手动安装),只是在手机上无法通过软件商店看到该程序罢了。如果程序所在的软件商店没有检测到<compatible-screens>和<supports-screens>标签,这两个标签将被忽略。
<compatible-screens>标签没有任何属性,但该标签中可以包含任意多个<screen>标签(可以不包含<screen>标签)。<screen>标签有如下两个属性。
android:screenSize:设置屏幕尺寸。
android:screenDensity:设置屏幕密度。
这两个属性必须同时指定,如果只指定一个属性,则该<screen>标签将被忽略。因此,对于同一类屏幕尺寸,要想支持所有的屏幕密度,需要枚举所有的值。
<manifest ... >
<compatible-screens>
<!--设置所有small等级屏幕支持的密度 -->
<screen android:screenSize="small" android:screenDensity="ldpi" />
<screen android:screenSize="small" android:screenDensity="mdpi" />
<screen android:screenSize="small" android:screenDensity="hdpi" />
<screen android:screenSize="small" android:screenDensity="xhdpi" />
<!-- 设置所有normal等级屏幕支持的密度 -->
<screen android:screenSize="normal" android:screenDensity="ldpi" />
<screen android:screenSize="normal" android:screenDensity="ldpi " />
<screen android:screenSize="normal" android:screenDensity="hdpi" />
<screen android:screenSize="normal" android:screenDensity="xhdpi" />
</compatible-screens>
...
<application ... >
...
<application>
</manifest>
虽然使用<compatible-screens>标签可以设置屏幕尺寸和屏幕密度,但略显麻烦,而对于Android 3.2及以上版本,最好使用<supports-screens>来代替<compatible-screens>标签。
<supports-screens>可以设置Android 3.2才开始支持的属性,例如,可以设置屏幕最小宽度,还可以用android:normalScreens、android:largeScreens等属性设置屏幕的尺寸,这些属性与<screen>标签的android:screenSizes属性的功能相同。只是前者是boolean类型(默认值为true),而后者是枚举类型。下面的设置可以告知软件商店该Android应用只支持7寸及以上尺寸的平板电脑。
<manifest ... >
<supports-screens android:smallScreens="false"
android:normalScreens="false"
android:largeScreens="true"
android:xlargeScreens="true"
android:requiresSmallestWidthDp="600" />
...
<application ... >
...
</application>
</manifest>
上面的配置代码通过如下两个方面描述了当前的Android应用。
屏幕尺寸只支持large和xlarge等级。
最小屏幕宽度至少应为600dp。
12.5.9 在Android模拟器上测试各种屏幕尺寸和密度
通常认为测试屏幕尺寸和密度就要使用相应规格的手机,不过最新版的ADT提供了自定义屏幕尺寸和密度的功能,可以完全在Android模拟器上测试这两个指标。
在建立AVD时,可以从“Device”列表中选择一个默认的屏幕尺寸,如图12-5所示。
▲图12-5 选择默认的屏幕尺寸
在运行AVD之前,会弹出如图12-6所示的对话框,通过“Screen Size”和“Monitor dpi”文本输入框可以修改当前屏幕的尺寸和密度。
▲图12-6 修改屏幕的尺寸和密度