谷歌推荐我们,在开发安卓系统应用程序的时候,要把资源从代码中分离出来,这样便于我们单独维护它们。采取分离的资源设计,我们还可以提供可选资源,支持特定的设备配置譬如不同的语言或屏幕尺寸,随着越来越多的Android设备可选用不同的配置,这变得越来越重要。为了提供不同配置的兼容性,你必须在你的项目的res/目录中组织资源。按类型和配置,使用不同的子目录。
对于任何类型的资源,你可以为你的应用程序提供一个默认和多个可选资源:
- 默认资源就是不管你什么配置我都强制使用或者没有满足配置的可选资源时使用的资源。
- 可选资源是提供给特定配置使用的资源。我们给res的自文件夹名提供一个配置限定符,从而把特定配置和特定可选资源关联起来。(【注】所以,这是一种高度分立的资源配置,我们不是在代码中通过if...else等条件语句来判断使用哪个可选资源,而是由系统的某个服务自动判断当前配置和资源文件夹名来加载合适的资源)
【注】:本文的资源是指res目录下的资源,资源还可以出现在assets目录下。
1、资源类型:
Directory | Resource Type |
---|---|
animator/ |
XML files that define property animations. |
anim/ |
XML files that define tween animations. (Property animations can also be saved in this directory, but the animator/ directory is preferred for property animations to distinguish between the two types.) |
color/ |
XML files that define a state list of colors. See Color State List Resource |
drawable/ |
Bitmap files (
See Drawable Resources. |
mipmap/ |
Drawable files for different launcher icon densities. For more information on managing launcher icons with mipmap/ folders, see Managing Projects Overview. |
layout/ |
XML files that define a user interface layout. See Layout Resource. |
menu/ |
XML files that define application menus, such as an Options Menu, Context Menu, or Sub Menu. See Menu Resource. |
raw/ |
Arbitrary files to save in their raw form. To open these resources with a raw However, if you need access to original file names and file hierarchy, you might consider saving some resources in the |
values/ |
XML files that contain simple values, such as strings, integers, and colors. Whereas XML resource files in other Because each resource is defined with its own XML element, you can name the file whatever you want and place different resource types in one file. However, for clarity, you might want to place unique resource types in different files. For example, here are some filename conventions for resources you can create in this directory:
See String Resources, Style Resource, and More Resource Types. |
xml/ |
Arbitrary XML files that can be read at runtime by calling Resources.getXML() . Various XML configuration files must be saved here, such as a searchable configuration. |
2、提供资源:
2.1、提供多选资源:
【注】在不同文件夹下的同组多选资源必须叫相同的名字,在R.java也只有一个ID对应于它们,属于一对多的关系。
2.2、利用资源提供最佳设备兼容性:
前面说到我们可以提供多选资源供系统动态选择,但有一点我们必须切记,那就是我们必须总是提供默认资源。这是因为我们一般不太可能提供所有可能的可选资源或者由于系统版本更新系统中新增了某些可选资源,如何系统配置需要的多选资源我们没有提供而又没有默认资源,那么系统就会崩溃。
对于这个规则有一个例外,在android sdk 4.0以上版本,我们的屏幕像素密度为后缀的drawable资源可以不用提供默认资源。
2.3、Android是如何找到最佳匹配资源的:
Providing the Best Device Compatibility with Resources
In order for your application to support multiple device configurations, it's very important that you always provide default resources for each type of resource that your application uses.
For example, if your application supports several languages, always include a values/
directory (in which your strings are saved) without a language and region qualifier. If you instead put all your string files in directories that have a language and region qualifier, then your application will crash when run on a device set to a language that your strings do not support. But, as long as you provide default values/
resources, then your application will run properly (even if the user doesn't understand that language—it's better than crashing).
Likewise, if you provide different layout resources based on the screen orientation, you should pick one orientation as your default. For example, instead of providing layout resources in layout-land/
for landscape and layout-port/
for portrait, leave one as the default, such as layout/
for landscape and layout-port/
for portrait.
3、访问资源:
(资源定义之后就涉及到怎么引用它的问题。这里的引用主要涉及两个方面:在程序中引用资源和在资源文件中引用资源。我们知道,res目录下的资源都会被自动编译到R.java文件中去,这是为了方便在程序中引用资源。资源文件中是不能引用R.java资源的,而是直接引用其它资源文件中的资源。——错误)
一旦在我们的应用程序中提供了一个资源,我们可以通过引用它的资源ID来应用它。所有资源ID都在我们的项目的R类中定义,R类是aapt工具自动生成的。当我们编译应用程序时,aapt产生R类,它包含res目录下所有资源的ID。对每一种类型的资源,都有一个R类的子类与之对应(譬如,R.drawable子类包括所有drawable资源的ID),资源ID是一个静态整数值(譬如R.drawable.icon
),通过这个整数值ID我们就可以获取这个资源。
虽然R类定义了我们应用程序的ID值,但我们却永远无需去这个文件查找资源ID的值。事实上,我们并不关心ID值,而只需关心ID名。一个资源ID名总是包含:
- 资源类型:譬如string, drawable, and layout。
- 资源名:它可以是:文件名(无需后缀);或者一个资源元素的XML android:name属性值(资源是简单值,譬如一个字符串)。
这两者以什么形式组成资源ID名呢?要看我们是在哪里引用资源,我们有两种引用资源的方式:
- 在代码中:使用一个R类子类的静态整数值,譬如:R.string.hello(其中,string是资源类型,hello是资源名)
- 在xml文件中:在xml中,我们也可以应用R类子类中定义的资源ID,譬如:@string/hello(@的含义后面讲到)
3.1、在代码中访问资源:
在代码中,我们可以通过把资源ID作为参数传给函数来使用资源。譬如,存在res/drawable/myimage.png文件,我们可以通过setImageResource(R.drawable.myimage)建立一个ImageView。
java code: ImageView imageView = (ImageView) findViewById(R.id.myimageview);
imageView.setImageResource(R.drawable.myimage);
You can also retrieve individual resources using methods in Resources
, which you can get an instance of with getResources()
.
Syntax
Here's the syntax to reference a resource in code:
[<package_name>.]R.<resource_type>.<resource_name>
-
<package_name>
is the name of the package in which the resource is located (not required when referencing resources from your own package). -
<resource_type>
is theR
subclass for the resource type. -
<resource_name>
is either the resource filename without the extension or theandroid:name
attribute value in the XML element (for simple values).
See Resource Types for more information about each resource type and how to reference them.
Use cases
There are many methods that accept a resource ID parameter and you can retrieve resources using methods in Resources
. You can get an instance of Resources
with Context.getResources()
.
Here are some examples of accessing resources in code:
// Load a background for the current screen from a drawable resourcegetWindow()
.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 IDgetWindow()
.setTitle
(getResources().getText
(R.string.main_title)); // Load a custom layout for the current screensetContentView
(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);
Caution: You should never modify the R.java
file by hand—it is generated by the aapt
tool when your project is compiled. Any changes are overridden next time you compile.
Accessing Resources from XML
You can define values for some XML attributes and elements using a reference to an existing resource. You will often do this when creating layout files, to supply strings and images for your widgets.
For example, if you add a Button
to your layout, you should use a string resource for the button text:
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/submit" />
Syntax
Here is the syntax to reference a resource in an XML resource:
@[<package_name>:]<resource_type>/<resource_name>
-
<package_name>
is the name of the package in which the resource is located (not required when referencing resources from the same package) -
<resource_type>
is theR
subclass for the resource type -
<resource_name>
is either the resource filename without the extension or theandroid:name
attribute value in the XML element (for simple values).
See Resource Types for more information about each resource type and how to reference them.
Use cases
In some cases you must use a resource for a value in XML (for example, to apply a drawable image to a widget), but you can also use a resource in XML any place that accepts a simple value. For example, if you have the following resource file that includes a color resource and a string resource:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="opaque_red">#f00</color>
<string name="hello">Hello!</string>
</resources>
You can use these resources in the following layout file to set the text color and text string:
<?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="@color/opaque_red"
android:text="@string/hello" />
In this case you don't need to specify the package name in the resource reference because the resources are from your own package. To reference a system resource, you would need to include the package name. For example:
<?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" />
Note: You should use string resources at all times, so that your application can be localized for other languages. For information about creating alternative resources (such as localized strings), see Providing Alternative Resources. For a complete guide to localizing your application for other languages, see Localization.
You can even use resources in XML to create aliases. For example, you can create a drawable resource that is an alias for another drawable resource:
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/other_drawable" />
This sounds redundant, but can be very useful when using alternative resource. Read more about Creating alias resources.
Referencing style attributes
A style attribute resource allows you to reference the value of an attribute in the currently-applied theme. Referencing a style attribute allows you to customize the look of UI elements by styling them to match standard variations supplied by the current theme, instead of supplying a hard-coded value. Referencing a style attribute essentially says, "use the style that is defined by this attribute, in the current theme."
To reference a style attribute, the name syntax is almost identical to the normal resource format, but instead of the at-symbol (@
), use a question-mark (?
), and the resource type portion is optional. For instance:
?[<package_name>:][<resource_type>/]<resource_name>
For example, here's how you can reference an attribute to set the text color to match the "primary" text color of the system theme:
<EditText id="text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="?android:textColorSecondary"
android:text="@string/hello_world" />
Here, the android:textColor
attribute specifies the name of a style attribute in the current theme. Android now uses the value applied to the android:textColorSecondary
style attribute as the value for android:textColor
in this widget. Because the system resource tool knows that an attribute resource is expected in this context, you do not need to explicitly state the type (which would be ?android:attr/textColorSecondary
)—you can exclude the attr
type.
Accessing Platform Resources
Android contains a number of standard resources, such as styles, themes, and layouts. To access these resource, qualify your resource reference with the android
package name. For example, Android provides a layout resource you can use for list items in a ListAdapter
:
setListAdapter
(newArrayAdapter
<String>(this, android.R.layout.simple_list_item_1, myarray));
In this example, simple_list_item_1
is a layout resource defined by the platform for items in a ListView
. You can use this instead of creating your own layout for list items. For more information, see the List View developer guide.
4、具体资源类型介绍:
4.1、drawable
:
4.1.1、Bitmap files:
4.1.2、Nine-Patches (re-sizable bitmaps):
4.1.3、State lists:
状态列表用于根据对象的状态不同在同一个图形框中显示不同的图像。譬如,一个按钮有不同的状态(被按下,有焦点,或者两者都不是),我们可以根据状态的不同,给按钮配不同的背景图像。
我们可以在XML文件中描述状态表。一个状态表只有一个<selector>
和若干<item>
子元素。<item>用不同的属性描述状态,
对象状态改变时,系统从上到下匹配<item>状态属性,第一个满足的会被使用(注意不是最佳匹配,而是遇到满足的就停止匹配)。
You can describe the state list in an XML file. Each graphic is represented by an <item>
element inside a single <selector>
element. Each <item>
uses various attributes to describe the state in which it should be used as the graphic for the drawable.
During each state change, the state list is traversed top to bottom and the first item that matches the current state is used—the selection is not based on the "best match," but simply the first item that meets the minimum criteria of the state.
4.1.4、Layer List:
4.1.5、Level List:
4.1.6、Transition Drawable:
4.1.7、Inset Drawable:
4.1.8、Clip Drawable:
4.1.9、Scale Drawable:
4.1.10、Shape Drawable:
4.1.11、Animation drawables:
4.1.12、Color:
颜色资源也可以在XML中作为drawable使用,譬如在state list<item>元素的android:drawable属性(android:drawable="@color/green"
)。
4.2、style:
一个stype资源定义了UI的版式和外观。一个style可以应用于单个视图(在一个layout文件中使用)或者一整个Activity或者应用程序(在manifest文件中使用)。关于更多创建和应用style资源的话题,参见Styles and Themes.
【注】:style是一种简单资源,我们是通过<style>元素的name属性而不是XML文件名来标识它。所以我们可以把它跟其他简单资源放在一个XML文件中,以<resource>元素为父元素。
- 文件的位置:
res/values/filename.xml
- 文件名可以任选。元素名才是资源ID名。
- 资源的引用:
- XML:
@[package:]style/style_name
- syntax:
- 元素:
-
<resources>
- 必选元素,且必须是根元素。没有属性。
<style>
- 定义一个单独style。包含<item>元素。
- 属性:
name
- 字符串,必选,style的名字.
parent
- Style资源,这个style会继承父style资源的属性。
<item>
- 为style定义一个单个特性,必须是<style>元素的子元素。
- 属性:
name
- 属性资源,必选,要定义的style特性的名字(一般为系统属性,譬如:
android:textColor
)。