资料来源于官方api文档
Android资源文件之创建与访问
Android适配之创建别名资源
如果你想将某一资源用于多种设备配置(但是不想作为默认资源提供), 则无需将同一资源放入多个备用资源目录中。相反,可以(在某些情况下)创建备用资源,充当保存在默认资源目录下的资源的别名。
注: 并非所有资源都会提供相应的机制让你创建指向其他资源的别名。特别是, xml/目录中的动画资源、菜单资源、原始资源以及其他未指定的资源均不提供此功能。
例如,加入你有有一个应用图片icon.jpg, 并且需要不同区域设置独特版本。但是,加拿大英语和加拿大法语这两种区域设置需要同一版本。你可能会认为需要将相同的图像复制到加拿大英语和法语对应的资源目录中,但事实并非如此,相反,你可以将二者的图像另存为icon_ca.png(除icon.png以外的任何名称),并将其放入默认res/drawable/
目录中。然后,在res/drawable-en-rCA/
和res/drawable-fr-rCA/
中创建icon.xml
文件,使用<bitmap
>元素引用icon_ca.png
资源。这样,您只需要储存PNG文件的一个版本和两个指向该版本的小型xml文件。(XML文件示例如下)
Drawable
要创建指向现有 Drawable
的别名, 请使用<bitmap
>元素。例如:
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/icon_ca"/>
如果将此文件另存为icon.xml
(例如,在备用资源目录中,另存为res/drawable-en-rCA/
),则会编译到可作为R.drawable.icon
引用的资源中,但实际上它是R.drawable.icon_ca
资源(保存在res/drawable/
中)的别名。
布局
要创建指向现有布局的别名,请使用包装在<merge
>中的<include
>元素。例如:
<?xml version="1.0" encoding="utf-8"?>
<merge>
<include layout="@layout/main_ltr"/>
</merge>
如果将此文件另存为main.xml
,则会编译到可作为R.layout.main
引用的资源中, 但实际上它是R.lyout.main_ltr
资源的别名。
字符串和其他简单值
要创建指向现有字符串的别名, 只需要将所需字符串的资源ID用作新字符串的值即可。例如:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello</string>
<string name="hi">@string/hello</string>
</resources>
R.string.hi
资源现在是R.string.hello
的别名
其他简单值的原理相同。 例如,颜色:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="yellow">#f00</color>
<color name="highlight">@color/red</color>
</resources>
利用资源提供最佳设备兼容性
为了提供最佳设备兼容性,请始终为应用正确运行所必需的资源提供默认资源。然后,使用配置限定符为特定的设备配置创建备用资源。
这条规则有一个例外:如果应用的 minSdkVersion 为 4 或更高,则在提供带屏幕密度限定符的备用 Drawable 资源时,不需要默认 Drawable 资源。 即使没有默认 Drawable 资源,Android 也可以从备用屏幕密度中找到最佳匹配项并根据需要缩放位图。 但是,为了在所有类型的设备上提供最佳体验,您应该为所有三种类型的密度提供备用 Drawable。
Android 如何找到最匹配资源
当您请求要为其提供备用资源的资源时,Android会根据当前的设备配置选择要在运行时使用的备用资源。为演示 Android如何选择备用资源,假设以下 Drawable 目录分别包含相同图像的不同版本:
drawable/
drawable-en/
drawable-fr-rCA/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/
同时,假设设备配置如下:
区域设置 = en-GB
屏幕方向 = port
屏幕像素密度 = hdpi
触摸屏类型 = notouch
主要文本输入法 = 12key
通过将设备配置与可用的备用资源进行比较,Android 从 drawable-en-port
中选择 Drawable
。
系统使用以下逻辑决定要使用的资源:
1. 淘汰与设备配置冲突的资源文件。
drawable-fr-rCA/
目录与 en-GB 区域设置冲突,因而被淘汰。
drawable/
drawable-en/
drawable-fr-rCA/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/
例外:屏幕像素密度是唯一一个未因冲突而被淘汰的限定符。 尽管设备的屏幕密度为
hdpi
,但是drawable-port-ldpi/
未被淘汰,因为此时每个屏幕密度均视为匹配。
2. 选择列表中(下一个)优先级最高的限定符。(先从 MCC 开始,然后下移。)
3. 是否有资源目录包括此限定符?
- 若无,请返回到第2步,看看下一个限定符。(在该示例中,除非达到语言限定符,否则答案始终为“否”。)
- 若有,请继续执行第 4 步。
4. 淘汰不含此限定符的资源目录。在该示例中,系统会淘汰所有不含语言限定符的目录。
例外:如果涉及的限定符是屏幕像素密度,则 Android 会选择最接近设备屏幕密度的选项。通常,Android 倾向于缩小大型原始图像,而不是放大小型原始图像。
5. 返回并重复第 2 步、第 3 步和第 4 步,直到只剩下一个目录为止。在此示例中,屏幕方向是下一个判断是否匹配的限定符。因此,未指定屏幕方向的资源被淘汰:
访问资源
代码访问资源
[<package_name
>.]R.<resource_type
>.<recource_name
>
- <
package_name
> 资源所在包的名称(如果引用的资源来自于你自己的资源包,则不需要). - <
resource_type
> 资源类型的R子类。 - <
resource_name
> 是不带扩展名的资源文件名,或XML元素中的android:name
属性值(如果资源是简单值)
// Load a background for the current screen from a drawable resource
getWindow().setBackgroundDrawableResource(R.drawable.my_background_image) ;
// Set the Activity title by getting a string from the Resources object, because
// this method requires a CharSequence rather than a resource ID
getWindow().setTitle(getResources().getText(R.string.main_title));
// Load a custom layout for the current screen
setContentView(R.layout.main_screen);
// Set a slide in animation by getting an Animation from the Resources object
mFlipper.setInAnimation(AnimationUtils.loadAnimation(this,
R.anim.hyperspace_in));
// Set the text on a TextView object using a resource ID
TextView msgTextView = (TextView) findViewById(R.id.msg);
msgTextView.setText(R.string.hello_message);
在XML中访问资源
语法
[<package_name
>.]R.<resource_type
>.<recource_name
>
- <package_name> 是资源所在包的名称(如果引用的资源来自同一包,则不需要)
- <resource_type> 是资源类型的 R 子类
- <resource_name> 是不带扩展名的资源文件名,或 XML 元素中的 android:name 属性值(如果资源是简单值)。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="opaque_red">#f00</color>
<string name="hello">Hello!</string>
</resources>
<!-- 要引用系统资源,您需要加入包名称 -->
<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textColor="@android:color/secondary_text_dark"
android:text="@string/hello" />
引用样式属性
您可以通过样式属性资源在当前应用的风格主题中引用某个属性的值。 通过引用样式属性,您可以不采用为 UI 元素提供硬编码值这种方式,而是通过为 UI 元素设置样式,使其匹配当前风格主题提供的标准变型来定制这些元素的外观。引用样式属性的实质作用是,“在当前风格主题中使用此属性定义的样式”。
要引用样式属性,名称语法几乎与普通资源格式完全相同,只不过将 at 符号 (@) 改为问号 (?),资源类型部分为可选项。 例如:
?[<package_name>:][<resource_type>/]<resource_name>
<!--将文本颜色设置为与系统风格主题的“主要”文本颜色匹配-->
<EditText id="text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="?android:textColorSecondary"
android:text="@string/hello_world" />
访问平台资源
Android 包含许多标准资源,例如样式、风格主题和布局。要访问这些资源,请通过 android 包名称限定您的资源引用。例如,您可以将 Android 提供的布局资源用于 ListAdapter 中的列表项:
//simple_list_item_1 是平台为 ListView 中的项目定义的布局资源。您可以使用它,而不必自行创建列表项布局。
setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myarray));