Android Studio 的res/values文件夹为开发者提供了自定义资源文件的能力。参考Google的文档,记录一下。
一、将资源放入res目录下指定的子目录下。res目录下支持的资源目录如下:
animator/
用于定义属性动画的 XML 文件。
anim/
定义渐变动画的 XML 文件。(属性动画也可以保存在此目录中,但是为了区分这两种类型,属性动画首选 animator/
目录。)
color/
用于定义颜色状态列表的 XML 文件。
drawable/
位图文件(.png
、.9.png
、.jpg
、.gif
)或编译为以下可绘制对象资源子类型的 XML 文件:位图文件;九宫格(可调整大小的位图);状态列表;形状;动画可绘制对象;其他可绘制对象。
mipmap/
适用于不同启动器图标密度的可绘制对象文件。
layout/
用于定义用户界面布局的 XML 文件。
menu/
用于定义应用菜单(如选项菜单、上下文菜单或子菜单)的 XML 文件。
raw/
要以原始形式保存的任意文件。要使用原始 InputStream
打开这些资源,请使用资源 ID(即 R.raw.filename
)调用 Resources.openRawResource()
。
但是,如需访问原始文件名和文件层次结构,则可以考虑将某些资源保存在 assets/
目录下(而不是 res/raw/
)。assets/
中的文件没有资源 ID,因此您只能使用 AssetManager
读取这些文件。
values/
包含字符串、整型数和颜色等简单值的 XML 文件。其他 res/
子目录中的 XML 资源文件是根据 XML 文件名定义单个资源,而 values/
目录中的文件可描述多个资源。对于此目录中的文件, <resources>
元素的每个子元素均定义一个资源。例如,<string>
元素创建 R.string
资源,<color>
元素创建 R.color
资源。
由于每个资源均用其自己的 XML 元素定义,因此您可以根据自己的需要命名文件,并将不同的资源类型放在一个文件中。但是,为了清晰起见,您可能需要将独特的资源类型放在不同的文件中。 例 如,对于可在此目录中创建的资源,下面给出了相应的文件名约定:arrays.xml,用于资源数组(类型化数组)。colors.xml:颜色值。dimens.xml:尺寸值。strings.xml:字符串值。styles.xml:样式。
解释一下values文件夹这段话:谷歌的意思是除了values文件下的资源文件都是根据xml文件名来引用的,但是values文件夹下的资源文件则是根据子元素类型来引用的。你可以在values下新建任意名称的文件,在其中定义自己的资源,最后只需要通过getResource().getString(R.String.xxx)来引用。但是为了整齐划一,谷歌给我们规范了这几种资源类型的文件名,但你可以不用,或者另起炉灶建其他文件名,只要在values下的某个文件中的<resources>标签下定义了你想要的资源标签和值。例如在values文件夹下建立custom.xml文件,在里面定义
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="boolean_value">true</bool>
<string name="custom_string">这是在values下自定义的字符串</string>
<dimen name="custom_text_font">18sp</dimen>
</resources>通过getResources().getDimensionPixelSize(R.dimen.custom_text_font)使用。
切勿将资源文件直接保存在res目录下,编译会报错。以上是安卓的默认资源。除此之外,对于屏幕尺寸超过标准大小的设备或者设置了不同语言类型的系统,还需要准备不同的布局资源和字符串文本资源。这些称为备用资源。
二、备用资源
如上图所示,不同类型设备或者不同地区的设备需要有多个资源。Android会在运行时检测设备的配置并加载合适的资源文件。安卓通过一下方式来指定不同的资源文件:
- 在
res/
中创建一个以<resources_name>-<config_qualifier>
形式命名的新目录。<resources_name>
是相应默认资源的目录名称(如一中所定义的资源目录)。<qualifier>
是指定要使用这些资源的各个配置的名称(请参阅https://developer.android.com/guide/topics/resources/providing-resources.html)。
您可以追加多个
<qualifier>
。以短划线将其分隔。注意:追加多个限定符时,必须按照表 2 (参阅上方链接)中列出的相同顺序放置它们。如果限定符的顺序错误,则该资源将被忽略。
- 将相应的备用资源保存在此新目录下。这些资源文件的名称必须与默认资源文件完全一样。
例如:
res/
drawable/
icon.png
background.png
drawable-hdpi/
icon.png
background.png
在使用备用资源的配置限定符名称时,安卓规定了一些规则:
- 您可以为单组资源指定多个限定符,并使用短划线分隔。例如,
drawable-en-rUS-land
适用于横排美国英语设备。 - 这些限定符必须遵循表 2(上方红色链接) 中列出的顺序。例如:
- 错误:
drawable-hdpi-port/
- 正确:
drawable-port-hdpi/
- 错误:
- 不能嵌套备用资源目录。例如,您不能拥有
res/drawable/drawable-en/
。 - 值不区分大小写。在处理之前,资源编译器会将目录名称转换为小写,以避免不区分大小写的文件系统出现问题。 名称中使用的任何大写字母只是为了便于认读。
- 对于每种限定符类型,仅支持一个值。例如,若要对西班牙语和法语使用相同的可绘制对象文件,则您肯定不能拥有名为
drawable-rES-rFR/
的目录,而是需要两个包含相应文件的资源目录,如drawable-rES/
和drawable-rFR/
。然而,实际上您无需将相同的文件都复制到这两个位置。相反,您可以创建指向资源的别名。实际就是对一个原始资源的多次引用。
将备用资源保存到以这些限定符命名的目录中之后,Android 会根据当前设备配置在应用中自动应用这些资源。 每次请求资源时,Android 都会检查备用资源目录是否包含所请求的资源文件,然后查找最佳匹配资源(下文进行介绍)。 如果没有与特定设备配置匹配的备用资源,则 Android 会使用相应的默认资源(一组用于不含配置限定符的特定资源类型的资源)。
要使应用支持多种设备配置,则务必为应用使用的每种资源类型提供默认资源,这一点非常重要,否则可能会出现应用在部分地区语言或者设备上崩溃。关于Android如何查找最佳匹配资源可参见链接。大致如下:第一步,淘汰含有与系统设置冲突的限定符的资源文件。第二步,选择列表(表 2)中(下一个)优先级最高的限定符。(先从 MCC 开始,然后下移。)第三步,是否有资源目录包括此限定符?若无,请返回到第 2 步,看看下一个限定符。(在该示例中,除非达到语言限定符,否则答案始终为“否”。)若有,请继续执行第 4 步。第四步,淘汰不含此限定符的资源目录。在该示例中,系统会淘汰所有不含语言限定符的目录。如果涉及的限定符是屏幕像素密度,则 Android 会选择最接近设备屏幕密度的选项。通常,Android 倾向于缩小大型原始图像,而不是放大小型原始图像。请参阅支持多种屏幕。
第五步,返回并重复第 2 步、第 3 步和第 4 步,直到只剩下一个目录为止。在此示例中,屏幕方向是下一个判断是否匹配的限定符。因此,未指定屏幕方向的资源被淘汰:
drawable-en/ drawable-en-port/ drawable-en-notouch-12key/
剩下的目录是 drawable-en-port
。
尽管对所请求的每个资源均执行此程序,但是系统仍会对某些方面做进一步优化。 例如,系统一旦知道设备配置,即会淘汰可能永远无法匹配的备用资源。 比如说,如果配置语言是英语(“en”),则系统绝不会将语言限定符设置为非英语的任何资源目录包含在选中的资源池中(不过,仍会将不带语言限定符的资源目录包含在该池中)。
根据屏幕尺寸限定符选择资源时,如果没有更好的匹配资源,则系统将使用专为小于当前屏幕的屏幕而设计的资源(例如,如有必要,大尺寸屏幕将使用标准尺寸的屏幕资源)。 但是,如果唯一可用的资源大于当前屏幕,则系统不会使用这些资源,并且如果没有其他资源与设备配置匹配,应用将会崩溃(例如,如果所有布局资源均用 xlarge
限定符标记,但设备是标准尺寸的屏幕)。
注:限定符的优先顺序(表 2 中)比与设备完全匹配的限定符数量更加重要。例如,在上面的第 4 步中,列表剩下的最后选项包括三个与设备完全匹配的限定符(方向、触摸屏类型和输入法),而 drawable-en
只有一个匹配参数(语言)。但是,语言的优先顺序高于其他两个限定符,因此 drawable-port-notouch-12key
被淘汰。