开发者应始终外部化应用资源,以便单独对其进行维护。
分组资源类型
项目res/
目录中支持的常用资源目录:
目录 | 资源类型 |
---|---|
animator/ | 用于定义属性动画的 XML 文件 |
anim/ | 用于定义渐变动画的 XML 文件(属性动画也可保存在此目录中) |
color/ | 用于定义颜色状态列表的 XML 文件 |
drawable/ | 位图文件或编译为可绘制对象资源子类型的 XML 文件 |
mipmap/ | 适用于不同启动器图标密度的可绘制对象文件 |
layout/ | 用于定义用户界面布局的 XML 文件 |
menu/ | 用于定义应用菜单的 XML 文件 |
raw/ | 需以原始形式保存的任意文件 |
values/ | 包含字符串、整型数和颜色等简单值的 XML 文件。 对于此目录中的文件,<resources> 元素的每个子元素均会定义一个资源。 由于每个资源均使用自己的 XML 元素进行定义,因此可以随意命名文件,并在某个文件中放入不同的资源类型。但是,可能需要将独特的资源类型放在不同的文件中,使其一目了然,下面给出了相应的文件名约定:arrays.xml:资源数组(类型数组)。colors.xml:颜色值。dimens.xml:尺寸值。strings.xml:字符串值。styles.xml:样式。 |
xml/ | 可在运行时读取的任意 XML 文件 |
上述子目录中,保存的资源为默认资源。如要为不同设备配置提供这些不同资源,还需提供备用资源。
提供备用资源
为一组资源指定配置特定的备用资源:
- 在
res/
中创建以<resources_name>-<config_qualifier>
形式命名的新目录。<resources_name>
是相应默认资源的目录名称。<qualifier>
是指定要使用这些资源的各个配置的名称。可以按下表优先级顺序追加多个<qualifier>
,以短划线将其分隔。 - 将相应的备用资源保存在此新目录下。这些资源文件必须与默认资源文件完全同名。
常用配置限定符名称:
配置 | 限定符值 | 说明 |
---|---|---|
语言、脚本(可选)和区域(可选) | 示例:en fr-rCA | 语言通过由两个字母组成的语言代码进行定义,可以选择后跟两个字母组成的区域码(前缀用小写字母 r) |
最小宽度 | sw<N>dp | 设备的 smallestWidth 是屏幕可用高度和宽度的最小尺寸。无论屏幕的当前方向如何,均可使用此限定符确保应用界面的可用宽度至少为 <N> dp |
屏幕宽高比 | long notlong | long:宽屏,notlong:非宽屏 此配置完全基于屏幕的纵横比(long 屏较宽),与屏幕方向无关 |
屏幕方向 | port land | port:设备处于纵向 land:设备处于横向状态 |
夜间模式 | night notnight | night:夜间 notnight:白天 |
屏幕像素密度 (dpi) | ldpi mdpi hdpi xhdpi xxhdpi xxxhdpi | ldpi:低密度屏幕;约为 120dpi mdpi:中等密度屏幕;约为 160dpi hdpi:高密度屏幕;约为 240dpi xhdpi:超高密度屏幕;约为 320dpi xxhdpi:绝高密度屏幕;约为 480dpi xxxhdpi:极高密度屏幕使用(仅限启动器图标);约为 640dpi 六个基本密度之间的缩放比为 3:4:6:8:12:16。因此,9x9 (ldpi) 位图相当于 12x12 (mdpi)、18x18 (hdpi)、24x24 (xhdpi) 位图,依此类推。 |
键盘可用性 | keysexposed keyshidden keyssoft | keysexposed:设备拥有可用的键盘(启用了软键盘或配备了硬键盘) keyshidden:设备硬键盘处于隐藏状态,且设备未启用软键盘 keyssoft:设备已启用软键盘 |
平台版本(API 级别) | 示例:v7 | 设备支持的 API 级别 |
限定符命名规则
- 不能嵌套备用资源目录。例如,目录不能为
res/drawable/drawable-en/
- 值不区分大小写
- 每种限定符类型仅支持一个值
创建别名资源
如果想将某一资源用于多种设备配置(但不想以默认资源的形式提供该资源),则无需将同一资源放入多个备用资源目录中。相反,可以(在某些情况下)创建备用资源,充当默认资源目录中所保存资源的别名。
例如,将图像保存为music_zh.png
(除music.png
以外的任何名称),并将其放入默认的res/drawable/
目录中。然后,在res/drawable-zh/
中创建music.xml
文件,如下:
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/music_zh" />
或者创建指向现有可绘制对象的别名,如下。在备用资源目录中保存为res/values-zh/
,则系统会将其编译到可作为R.drawable.music
引用的资源中,但该文件实际是R.drawable.music_zh
资源(保存在res/drawable/
中)的别名。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<drawable name="music">@drawable/music_zh</drawable>
</resources>
访问应用资源
在代码中访问资源
语法:[<package_name>.]R.<resource_type>.<resource_name>
在 XML 中访问资源
语法:@[<package_name>:]<resource_type>/<resource_name>
引用样式属性
语法:?[<package_name>:][<resource_type>/]<resource_name>
例如,以下代码展示了如何通过引用属性来设置文本颜色,使其匹配系统主题背景的“基本”文本颜色。由于系统资源工具知道此环境中肯定存在某个属性资源,因此无需显式声明类型(类型应为?android:attr/textColorSecondary
)
<EditText id="text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="?android:textColorSecondary"
android:text="@string/hello_world" />
访问原始文件
如果需要访问原始文件和目录,可以将资源保存在assets/
目录中。
不过,如果只需要读取原始数据(例如视频文件或音频文件)的能力,则可将文件保存在res/raw/
目录中,并利用openRawResource()
读取字节流。
访问平台资源
Android 包含许多标准资源。如要访问这些资源,通过android
包名称限定资源引用。例如:
setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myarray));
利用资源提供最佳设备兼容性
为使应用支持多种设备配置,务必为应用使用的每种资源类型提供默认资源。
例如,如果应用支持多种语言,需始终包含不带语言和区域限定符的values/
目录。相反,设备语言已设为字符串所不支持的语言,则应用在该设备上运行时将崩溃。
同样,如果根据屏幕方向提供不同的布局资源,则应选择一个方向作为默认方向。例如:layout/
用于横向,layout-port/
用于纵向。
提供默认资源至关重要,这不仅是因为应用可能会在超出预期的配置上运行,也因为新版 Android 有时会添加旧版本不支持的配置限定符。因此,为提供最佳的设备兼容性,请始终为应用正确运行所需的资源提供默认资源。
这条规则有一个例外:在提供带屏幕密度限定符的备用可绘制对象资源时,不需要默认可绘制对象资源,Android 会从备用屏幕密度中找到最佳匹配项并根据需要缩放位图。
Android 如何查找最佳匹配资源
系统使用以下逻辑决定要使用的资源:
- 淘汰与设备配置冲突的资源文件。例外:屏幕像素密度是唯一一个不因冲突而被淘汰的限定符。
- 选择配置限定符列表中(下一个)优先级最高的限定符。
- 是否有资源目录包含此限定符?若无,返回到第 2 步,看看下一个限定符。若有,继续执行第 4 步。
- 淘汰不含此限定符的资源目录。例外:如果问题中的限定符是屏幕像素密度,则 Android 会选择最接近设备屏幕密度的选项。
- 返回并重复第 2 步、第 3 步和第 4 步,直到仅剩一个目录为止。
参考资料:应用基础知识 > 应用资源 > 应用资源简介
应用基础知识#应用资源 | Android Developers
应用资源概览 | Android Developers