目录(?)[+]
遍布在世界各地的Android设备有许多形状和大小。通过范围广泛的设备类型,您的应用程序有机会得到一个数量巨大的受众。为了能够在Android上尽可能地成功,你的应用需要适应不同的设备配置。你应该考虑的一些重要变化包括不同的语言、屏幕尺寸和Android平台的版本。
这堂课教你如何使用基本的平台功能——利用替代资源和其他功能,让你的应用只使用一个单一的应用程序包(APK),却可以在各种兼容Android设备上提供优化的用户体验。
支持不同的语言
了解如何利用替代字符串资源支持多国语言。
支持不同的屏幕
了解如何为不同的屏幕大小和密度优化用户体验。
支持不同的平台版本
了解如何使用新版本的Android可用的API,仍能同时继续支持旧版本的Android。
从您的应用程序代码中提取UI字符串并把它们存放在一个外部文件,总是一个很好的做法。通过每个Android项目中的资源目录,Android使得这个做法的变得简单。
如果你使用了Android SDK工具创建你的项目(参考创建一个Android项目),该工具会在项目的顶层创建一个res/
目录。在这个res/
目录下,是各种资源类型的子目录。还有一些默认的文件,如 res/value/strings.xml
,它保存字符串的值。
要添加更多语言的支持,在res/目录下创造另外的values
目录,这些目录包含一个连字符和ISO国家代码。例如,values-es/
是
目录含有以“es”作为语言代码的环境下的简单资源。Android根据设备在运行时的区域设置加载合适的资源。
一旦你决定了你要支持的语言,创建的资源的子目录和字符串资源文件。例如:
MyProject/
res/
values/
strings.xml
values-es/
strings.xml
values-fr/
strings.xm
为每个区域添加字符串值到相应的文件。
Android系统在运行时,根据用户的设备上目前的语言环境设置,使用相应的一组字符串资源。
例如,以下是一些不同语言的不同字符串资源文件。
英语(默认语言环境)/values/strings.xml
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="title">My Application</string>
<string name="hello_world">Hello World!</string>
</resources>
西班牙语/values-es/strings.xml
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="title">Mi Aplicación</string>
<string name="hello_world">Hola Mundo!</string>
</resources>
法语/values-fr/strings.xml
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="title">Mon Application</string>
<string name="hello_world">Bonjour le monde !</string>
</resources>
注:您可以对任何资源类型的使用场景限定符(或任何配置限定符),例如,你要提供你的位图的本地化版本。如需了解更多信息,请参阅本地化。
你可以在你的源代码和其他XML文件,使用<String>
的
元素的name
属性定义的资源名称引用字符串资源。
在你的源代码,你可以通过语法R.string.<string_name>
引用一个字符串资源。有很多这种接受字符串资源的方法。
例如:
// Get a string resource from your app'sResources
String hello =getResources().getString(R.string.hello_world);
// Or supply a string resource to amethod that requires a string
TextView textView = new TextView(this);
textView.setText(R.string.hello_world);
在其他的XML文件中,你可以在XML属性需要得到一个字符串资源时,通过@string/ <string_name>
引用一个字符串值。
例如:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world"/>
对Android设备屏幕进行分类,一般使用两个属性:尺寸和密度。你应该预料到你的应用程序将被安装在不同范围的尺寸和密度屏幕的设备上。因此,您应该包含一些可替换资源,针对不同的屏幕大小和密度,优化你的应用程序的外观。
· 有四种普遍的尺寸:小(small),正常(normal),大(large),超大(xlarge)
· 也有4种普遍的密度:低(ldpi),中(mdpi),高(hdpi),超高(xhdpi)
声明你要在不同的屏幕中使用的布局和位图,你必须在不同的目录中放置这些可替换的资源,就像你为不同的语言字符串所做的那样。
另外要注意,屏幕方向(横向或纵向)被认为是一个屏幕大小的变化,所以很多应用程序应该针对每个方向修改布局,来优化用户体验。
为了优化在不同的屏幕尺寸上用户体验,,你应该为每个你想支持的屏幕尺寸创建一个独一无二的布局XML文件。每个布局应该保存到适当的资源目录,与一个-
<screen_size>
后缀来
命名。例如,大屏幕唯一的布局应保存在 res/layout-large/
目录下
。
注: Android自动拉伸你的布局来正确地适应屏幕。因此,你的不同屏幕尺寸的布局,不需要担心UI元素的绝对大小,而是把重点放在影响用户体验的布局结构上(如重要视图相对于同级视图的大小或位置)。
例如,这个项目包含一个默认的布局和一个可替换的大 屏幕布局:
MyProject/
res/
layout/
main.xml
layout-large/
main.xml
文件名必须是完全一样的,但它们的内容是不同的,以便为相应的画面尺寸提供优化的用户界面。
只需像往常一样在你的应用程序中引用这个布局文件:
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
根据运行您的应用程序的设备屏幕尺寸,系统从布局目录加载适当的布局文件。关于Android是如何选择适当的资源的更多信息,可参考提供资源 指南。
再举一个例子,这里是一个有横向替换布局的项目:
MyProject/
res/
layout/
main.xml
layout-land/
main.xml
默认情况下,纵向使用layout/main.xml
文件。
如果你想为提供一个特殊的横向布局,包括在大屏幕上,那么你需要同时使用larger和land标识符:
MyProject/
res/
layout/ # default (portrait)
main.xml
layout-land/ # landscape
main.xml
layout-large/ # large (portrait)
main.xml
layout-large-land/ # large landscape
main.xml
注: Android 3.2及以上的系统,支持一个先进的指定屏幕尺寸的方法,这个方法允许你根据最小宽度和高度的与密度无关像素(DIP),为不同的屏幕尺寸指定资源文件。这节课不包括这项新技术。欲了解更多信息,请阅读多屏幕的设计。
你应该总是对各个普遍的密度桶(bucket)提供正确缩放的位图资源:低,中,高和超高密度。这可以帮助你在所有的屏幕密度上实现良好的图形质量和性能。
要生成这些图像,你的原始资源应该是矢量格式的,并为各个密度生成的图像使用下面的拉伸比例:
· xhdpi:2.0
· hdpi:1.5
· mdpi:1.0(基线)
· ldpi:0.75
这意味着,如果你为xhdpi设备生成一个200x200的图像,你应该为其它密度产生相同的资源:hdpi是150X150,mdpi是100x100,ldpi是75X75。
然后,将这些文件放在适当的绘制资源目录中:
MyProject/
res/
drawable-xhdpi/
awesomeimage.png
drawable-hdpi/
awesomeimage.png
drawable-mdpi/
awesomeimage.png
drawable-ldpi/
awesomeimage.png
任何时候你引用@drawable/awesomeimage
,系统根据屏幕的密度选择合适的位图。
注意:低密度(ldpi)的资源并非总是必要的。当你提供hdpi的资产,系统会把它们缩小一半来正确地适应ldpi屏幕。
关于您的应用程序创建图标资产的更多的提示和指引,请参阅 意象设计指南。
虽然最新版本的Android往往为您的应用程序提供了最好的的API,但你应该继续支持旧版本的Android,直至更多的设备得到更新。这节课告诉你如何利用最新的API,同时继续支持旧版本。
根据访问谷歌Play Store的Android设备数量,在平台版本 仪表板上定期更新,来显示运行每个Android版本的激活设备的分布。一般来说,支持约90%激活设备是一个很好的做法,同时针对您的应用程序到最新版本。
提示:为了提供跨Android版本的最好的特性和功能,你应该在你的应用程序使用Android Support Libraly,它允许您使用最近的几个平台上的旧版本的API 。
AndroidManifest.xml文件描述了你的应用程序的细节,并确定它支持的Android版本。具体来说,<
uses-sdk>
元素的minSdkVersion
和targetSdkVersion
属性识别与您的应用程序兼容的API最低级别,以及设计和测试您的应用程序的最高的API级别。
例如:
<manifestxmlns:android="http://schemas.android.com/apk/res/android" ...>
<uses-sdk android:minSdkVersion="4"android:targetSdkVersion="15"/>
...
</manifest>
随着新版本的Android被发布,一些风格和行为可能会发生变化。为了让您的应用程序以充分利用这些变化,并确保你的应用适合每个用户的设备的风格,你应该设置 targetSdkVersion
的
值匹配最新的Android版本。
Android在Build 常量类中为各平台版本提供了一个唯一的代码。在你的应用中使用这些代码构建条件,确保在依赖API级别较高的代码只在那些API在系统中可用时才会执行。
privatevoid setUpActionBar(){
// Make surewe're running on Honeycomb or higher to use ActionBar APIs
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB){
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
注:当解析XML资源,Android会忽略当前设备不支持的XML属性。所以,你可以放心地使用那些仅支持较新版本的XML属性,不用担心遇到这些代码时破坏旧版本。例如,如果你设置了 targetSdkVersion =“11”
,默认情况下,你的应用在Android3.0和更高版本中会包含ActionBar。然后要在操作栏中添加菜单项,你需要在你的菜单资源XML 中设置的android
:showAsAction =“ifRoom”
。在跨版本的XML文件中这样做是安全的,因为旧版本的Android根本无视 showAsAction
属性(也就是说,你并不需要一个独立的版本放在res/menu-v11/
目录下
)。
Android提供给应用程序的外观和感觉的底层操作系统的用户体验主题。这些主题可以应用到您的应用程序清单文件内。您的应用程序通过使用这些内置的风格和主题,自然会按照最新的外观和感觉的Android每一个新版本。
为了使您的活动看起来像一个对话框:
<activityandroid:theme="@android:style/Theme.Dialog">
为了使您的活动有一个透明的背景:
<activityandroid:theme="@android:style/Theme.Translucent">
要应用在/res/values/styles.xml
中
的自己的自定义主题:
<activityandroid:theme="@style/CustomTheme">
主题应用到整个应用程序(所有活动),添加android:theme
属性到<application>
元素的:
<applicationandroid:theme="@style/CustomTheme">
有关创建和使用主题的更多信息,请阅读的样式和主题指南。