六、Android应用的资源

1 资源的类型及存储方式 
2 使用字符串、颜色、尺寸资源 
3 数组(Array)资源 
4 使用(Drawable)资源 
5 属性动画(Property Animation)资源 
6 使用原始XML资源 
7 使用布局(Layout)资源 
8 使用菜单(Menu)资源 
9 样式(Style)和主题(Theme)资源 
10 属性(Attribute)资源 
11 使用原始资源 
12 国际化和资源自适应 
13 自适应不同屏幕的资源 

 

6.1 资源的类型及存储方式
◆ 无法通过R清单类访问的原生资源,保存在assets目录下。
◆ 可通过R资源清单类访问的资源,保存在res目录下。
【Android应用资源的存储】
/res/animator/ 存放定义属性动画的XML文件
/res/anim/ 存放定义补间动画的XML文件

/res/drawable/ 该目录下存放各种位图文件(如png, .9.png, jpg, gif)等。除此之外也能编译如下各种Drawable对象的XML文件:
# BitmapDrawable      
# NinePatchDrawable
# StateListDrawable
# ShapeDrawable
# AnimationDrawable  
# Drawable的其他各种子类的对象

xml标签名称                     类名称                                                说明

<animation-list>         AnimationDrawable                  建立由多个图像文件组成的动画,可以用来当成view对象的背景

<bitmap>                     BitmapDrawable                      可以让图像重复排列并适当地缩放和对齐

<clip>                          ClipDrawable                           用来剪裁Drawable对象

<color>                        ColorDrawable                         用来填上颜色

<rotate>                      RotateDrawable                        让Drawable对象旋转一个角度

<scale>                        ScaleDrawable                         缩放Drawable物件

<shape>                       GradientDrawable                    绘制特定形状,注意<shape>的对应类不是ShapeDrawable类

<transition>                 TransitionDrawable                  以淡入淡出的方式轮流显示一组图像
---------------------
drawable-ldpi(低分辨率)
drawable-mdpi(中等分辨率)
drawable-hdpi(高分辨率)
drawable-xhdpi(超高分辨率)
大部分程序、系统将会选择drawable-mdpi目录下的图片,如果系统使用高分屏,那么系统将会选择drawable-hdpi
目录下的图片文件。

/res/raw/
该目录下存放任意类型的原生资源(音频、视频文件等).在Java代码中可通过调用Resources对象的
openRawResource(int id)来获取该资源的二进制输入流,实际上,如果应用程序需要使用原生资源,
推荐把这些原生资源保存到/assets目录下,然后在应用程序中使用AssetManager来访问这些资源。

/res/values/
# arrays.xml 定义数组资源。
# colors.xml 定义原色值资源。
# dimens.xml 定义尺寸值资源。
# strings.xml 定义字符串资源。
# styles.xml 定义样式资源。

 

6.2 使用字符串、颜色、尺寸资源
(1)在Java代码中使用资源清单项(R)。

1 // 从drawable中加载图片,并设为该窗口的背景。
2 getWindow().setBackgroundDrawableResource(R.drawable.back);
3 // 从string中获取指定字符串资源,并设置该窗口的标题。
4 getWindow().setTitle(getResources().getText(R.string.title));
5 // 获取指定TextView组件,并设置该组件显示string资源中的指定字符串资源。
6 TextView msg = (TextView) findViewById(R.id.msg);
7 msg.setText(R.string.message);

(2)在Java代码中访问实际资源。

Resources主要提供了如下两类方法:
* getXxx(int id):根据资源清单ID来获取实际资源。
* getAssets():获取访问/assets/目录下资源的AssetManager对象。

范例:通过Resources获取实际字符串资源。

Resources res = getResources();
String title = res.getText(R.string.title);
Drawable logo = res.getDrawable(R.drawable.logo);
// 获取数组资源
int[] arr = res.getIntArray(R.array.books);

字符串资源 /res/values/strings.xml

颜色资源 /res/values/colors.xml
尺寸资源 /res/values/dimens.xml

【颜色值定义】
Android中的原色是通过红(Red)、绿(Green)、蓝(Blue)、三原色,以及一个透明度(Alpha)值来表示。颜色值总是以#开头,
接下来就是Alpha-Red-Green-Blue的形式。其中Alpha值可以省略,如果省略了Alpha值,那么该颜色默认是完全不透明的。

Android颜色值支持常见的4中形式:
◆ #RGB:分别指定红、绿、蓝三原色的值(只支持0-f这16级颜色)来代表颜色。
◆ #ARGB:分别指定红、绿、蓝三原色的值(只支持0-f这16级颜色)及透明度(只支持0-f这16级透明度)来代表颜色。
◆ #RRGGBB:分别指定红、绿、蓝三原色的值(支持00-ff这256级颜色)来代表颜色。
◆ #AARRGGBB:分别指定红、绿、蓝三原色的值(支持00-ff这256级颜色)以及透明度(支持00-ff这256级透明度)来代表颜色。

上面4中形式中,A、R、G、B都代表一个十六进制的数。
A代表透明度;R代表红色数值;
G代表绿色数值;B代表蓝色数值。

范例:使用字符串、颜色、尺寸资源

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center_horizontal">
<!-- 定义一个GridView组件,使用尺度资源中定义的长度来指定水平间距、垂直间距 -->
<GridView  
    android:id="@+id/grid01"
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:horizontalSpacing="@dimen/spacing"
    android:verticalSpacing="@dimen/spacing"
    android:numColumns="3"
    android:gravity="center" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="spacing">8dp</dimen>
    <!-- 定义GridView组件中每个单元格的宽度、高度 -->
    <dimen name="cell_width">60dp</dimen>
    <dimen name="cell_height">66dp</dimen>
    <!-- 定义主程序的标题的字体大小 -->
    <dimen name="title_font_size">18sp</dimen>
</resources>
 1 public class ValuesResTest extends Activity {
 2     // 使用字符串资源
 3     int[] textIds = new int[] { R.string.c1, R.string.c2, R.string.c3,
 4             R.string.c4, R.string.c5, R.string.c6, R.string.c7, R.string.c8,
 5             R.string.c9 };
 6     // 使用颜色资源
 7     int[] colorIds = new int[] { R.color.c1, R.color.c2, R.color.c3,
 8             R.color.c4, R.color.c5, R.color.c6, R.color.c7, R.color.c8,
 9             R.color.c9 };
10 
11     @Override
12     public void onCreate(Bundle savedInstanceState) {
13         super.onCreate(savedInstanceState);
14         setContentView(R.layout.main);
15         // 创建一个BaseAdapter对象
16         BaseAdapter ba = new BaseAdapter() {
17             @Override
18             public int getCount() {
19                 // 指定一共包含9个选项
20                 return textIds.length;
21             }
22             @Override
23             public Object getItem(int position) {
24                 // 返回指定位置的文本
25                 return getResources().getText(textIds[position]);
26             }
27             @Override
28             public long getItemId(int position) {
29                 return position;
30             }
31 
32             // 重写该方法,该方法返回的View将作为的GridView的每个格子
33             @Override
34             public View getView(int position, View convertView, ViewGroup parent) {
35                 TextView text = new TextView(ValuesResTest.this);
36                 Resources res = ValuesResTest.this.getResources();
37                 // 使用尺度资源来设置文本框的高度、宽度
38                 text.setWidth((int) res.getDimension(R.dimen.cell_width));
39                 text.setHeight((int) res.getDimension(R.dimen.cell_height));
40                 // 使用字符串资源设置文本框的内容
41                 text.setText(textIds[position]);
42                 // 使用颜色资源来设置文本框的背景色
43                 text.setBackgroundResource(colorIds[position]);
44                 text.setTextSize(20);
45                 text.setTextSize(getResources().getInteger(R.integer.font_size));
46                 return text;
47             }
48         };
49         GridView grid = (GridView) findViewById(R.id.grid01);
50         // 为GridView设置Adapter
51         grid.setAdapter(ba);
52     }
53 }

6.3 数组(Array)资源
Android 采用位于/res/values/目录下的arrays.xml文件来定义数组,定义数组时XML资源文件的跟元素也是<resources.../>元素,
该元素内可包含如下三种子元素。
# <array.../>子元素:定义普通类型的数组,例如Drawable数组。
# <string-array.../>子元素:定义字符串数组。
# <integer-array.../>子元素:定义证书数组。

Java程序访问到实际数组,Resources提供了如下方法:
# String[] getStringArray(int id):根据资源文件中的字符串数组资源的名称来获取实际的字符串数组。
# int[] getIntArray(int id):根据资源文件中整型数组资源的名称来获取实际的整型数组。
# TypedArray obtainTypedArray(int id):根据资源文件中普通数组资源的名称来获取实际的普通数组。

TypedArray代表了一个通用类型的数组,该类提供了getXxx(int index)来获取指定索引处的数组元素。

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <resources>
 3     <!-- 定义一个Drawable数组 -->
 4     <array name="plain_arr">
 5         <item>@color/c1</item>
 6         <item>@color/c2</item>
 7         <item>@color/c3</item>
 8     </array>
 9     <!-- 定义字符串数组 -->
10     <string-array name="string_arr">
11         <item>@string/c1</item>
12         <item>@string/c2</item>
13         <item>@string/c3</item>
14     </string-array>    
15     <!-- 定义字符串数组 -->
16     <string-array name="books">
17         <item>百度网站</item>
18         <item>谷歌网站</item>
19         <item>搜狐网站</item>
20     </string-array>
21 </resources>

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical" >
    <!-- 使用字符串资源,尺度资源 -->
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="@string/app_name"
        android:textSize="@dimen/title_font_size" />
    <!-- 定义一个GridView组件,使用尺度资源中定义的长度来指定水平间距、垂直间距 -->
    <GridView
        android:id="@+id/grid01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:horizontalSpacing="@dimen/spacing"
        android:numColumns="3"
        android:verticalSpacing="@dimen/spacing" />
    <!-- 定义ListView组件,使用了数组资源 -->
    <ListView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:entries="@array/books" />
</LinearLayout>

 

 1 public class ArrayResTest extends Activity {
 2     String[] texts;  // 获取系统定义的数组资源
 3 
 4     @Override
 5     public void onCreate(Bundle savedInstanceState) {
 6         super.onCreate(savedInstanceState);
 7         setContentView(R.layout.main);
 8         texts = getResources().getStringArray(R.array.string_arr);
 9         // 创建一个BaseAdapter对象
10         BaseAdapter ba = new BaseAdapter() {
11             @Override
12             public int getCount() {
13                 // 指定一共包含9个选项
14                 return texts.length;
15             }
16             @Override
17             public Object getItem(int position) {
18                 // 返回指定位置的文本
19                 return texts[position];
20             }
21             @Override
22             public long getItemId(int position) {
23                 return position;
24             }
25             // 重写该方法,该方法返回的View将作为的GridView的每个格子
26             @Override
27             public View getView(int position, View convertView, ViewGroup parent) {
28                 TextView text = new TextView(ArrayResTest.this);
29                 Resources res = ArrayResTest.this.getResources();
30                 // 使用尺度资源来设置文本框的高度、宽度
31                 text.setWidth((int) res.getDimension(R.dimen.cell_width));
32                 text.setHeight((int) res.getDimension(R.dimen.cell_height));
33                 // 使用字符串资源设置文本框的内容
34                 text.setText(texts[position]);
35                 TypedArray icons = res.obtainTypedArray(R.array.plain_arr);
36                 // 使用颜色资源来设置文本框的背景色
37                 text.setBackgroundDrawable(icons.getDrawable(position));
38                 text.setTextSize(20);
39                 return text;
40             }
41         };
42         GridView grid = (GridView) findViewById(R.id.grid01);
43         // 为GridView设置Adapter
44         grid.setAdapter(ba);
45     }
46 }

6.4 使用(Drawable)资源
【StateListDrawable】用于组织多个Drawable对象,当使用StateListDrawable作为目标组件的背景、前景图片时,
StateListDrawable对象所显示的Drawable对象会随目标组件状态的改变而自动切换。

定义StateListDrawable对象的XML的跟元素为<selector.../>,该元素可以包含多个<item.../>元素,该元素可指定如下属性:
# android:color或android:drawable:指定颜色或Drawable对象。
# android:state_xxx:指定一个特定状态。

★☆★ StateListDrawable支持的状态 ★☆★
android:state_active 代表是否处于激活状态
android:state_checkable 代表是否处于勾选状态
android:state_checked 代表是否处于已勾选状态
android:state_enabled 代表是否处于可用状态
android:state_first 代表是否处于开始状态
android:state_focused 代表是否处于已得到焦点状态
android:state_last 代表是否处于结束状态
android:state_middle 代表是否处于中间状态
android:state_pressed 代表是否处于已被按下状态
android:state_selected 代表是否处于已被选中状态
android:state_window_focused 代表是否窗口已得到焦点状态

范例:高亮显示正在输入的文本框

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout 
 3     xmlns:android="http://schemas.android.com/apk/res/android"
 4     android:layout_width="fill_parent"
 5     android:layout_height="fill_parent"
 6     android:orientation="vertical" >
 7     <!-- 使用StateListDrawable资源 -->
 8     <EditText
 9         android:layout_width="fill_parent"
10         android:layout_height="wrap_content"
11         android:textColor="@drawable/my_image" />
12     <EditText
13         android:layout_width="fill_parent"
14         android:layout_height="wrap_content"
15         android:textColor="@drawable/my_image" />
16 </LinearLayout>
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 指定获得焦点时的颜色 -->
    <item android:state_focused="true" android:color="#f44"/>
    <!-- 指定失去焦点时的颜色 -->
    <item android:state_focused="false" android:color="#eee"/>
</selector>

不仅可以让文本框里文字的颜色随文本框状态的改变而切换,也可让按钮的背景图片随按钮状态的改变而切换。

【LayerDrawable】
LayerDrawable可包含一个Drawable数组,因此系统将会按这些Drawable对象的数组顺序来绘制它们,索引最大的Drawable对象将会被绘制在最上面。

定义LayerDrawable对象的XML文件的跟元素为<layer-list.../>,该元素可以包含多个<item.../>元素,该元素可指定如下属性。
# android:drawable:指定作为LayerDrawable元素之一的Drawable对象。
# android:id:为该Drawable对象指定一个标识。
# android:button|top|left|button:它们用于指定一个长度值,用于指定将该Drawable对象绘制到目标组件的指定位置。

范例:定制拖动条的外观
前面知道,使用SeekBar时可指定一个android:progressDrawable属性,该属性可改变SeekBar的外观,借助于
LayerDrawable即可改变SeekBar的规定、已完成部分的Drawable对象。

a)定义如下Drawable资源,my_bar.xml

<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 定义轨道的背景 -->
    <item android:id="@android:id/background"
        android:drawable="@drawable/grow" />
    <!-- 定义轨道上已完成部分的外观-->
    <item android:id="@android:id/progress"
        android:drawable="@drawable/ok" />
</layer-list>     

b)定义三个“层叠”在一起的Drawable对象,layout_logo.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item>
        <bitmap
            android:gravity="center"
            android:src="@drawable/ic_launcher" />
    </item>
    <item
        android:left="25dp" android:top="25dp">
        <bitmap
            android:gravity="center"
            android:src="@drawable/ic_launcher" />
    </item>
    <item
        android:left="50dp" android:top="50dp">
        <bitmap
            android:gravity="center"
            android:src="@drawable/ic_launcher" />
    </item>
</layer-list>

c)布局文件。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <!-- 定义一个拖动条,并改变轨道外观 -->
    <SeekBar
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:max="100"
        android:progressDrawable="@drawable/my_bar" />
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/layout_logo" />
</LinearLayout>

 

【ShapeDrawable】
用于定义一个基本的几何图形(矩形、圆形、线条等),定义ShapeDrawable的XML文件的跟元素是<shape.../>元素,
该元素可指定如下属性:

http://jingyan.baidu.com/article/86112f13513f4127379787b0.html

android:shape=["rectangle"|"oval"|"line"|"ring"]:指定定义哪种类型的几何图形。

定义ShapeDrawable对象的完整语法格式如下:

<?xml version="1.0" encoding="utf-8"?>
<scale
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/drawable_resource"
    android:scaleGravity=["top" | "bottom" | "left" | "right" | "center_vertical" |
                          "fill_vertical" | "center_horizontal" | "fill_horizontal" |
                          "center" | "fill" | "clip_vertical" | "clip_horizontal"]
    android:scaleHeight="percentage"
    android:scaleWidth="percentage" />

范例:椭圆形、渐变背景的文本框
/drawable-mdpi/my_shape_1.xml

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <!-- 设置填充颜色 -->
    <solid android:color="#fff"/>
    <!-- 设置四周的内边距 -->
    <padding android:left="7dp" 
        android:top="7dp" 
        android:right="7dp" 
        android:bottom="7dp" />
    <!-- 设置边框 -->
    <stroke android:width="3dip" android:color="#ff0" />
</shape>

/drawable-mdpi/my_shape_2.xml

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="rectangle">
    <!-- 定义填充渐变颜色 -->
    <gradient 
        android:startColor="#FFFF0000" 
        android:endColor="#80FF00FF" 
        android:angle="45"/> 
    <!-- 设置内填充 -->
    <padding android:left="7dp" 
        android:top="7dp" 
        android:right="7dp" 
        android:bottom="7dp" />
    <!-- 设置圆角矩形 -->
    <corners android:radius="8dp" /> 
</shape>

/drawable-mdpi/my_shape_3.xml

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="oval">
    <!-- 定义填充渐变颜色 -->
    <gradient 
        android:startColor="#ff0" 
        android:endColor="#00f" 
        android:angle="45"
        android:type="sweep"/> 
    <!-- 设置内填充 -->
    <padding android:left="7dp" 
        android:top="7dp" 
        android:right="7dp" 
        android:bottom="7dp" />
    <!-- 设置圆角矩形 -->
    <corners android:radius="8dp" /> 
</shape>

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/my_shape_1" />
    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/my_shape_2" />
    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/my_shape_3" />
</LinearLayout>

【ClipDrawable】
代表从其他位图上截取一个“图片片段”,在XML中定义ClipDrawable使用<clip.../>,该元素的语法为:


上面的语法格式中可指定如下三个属性:
@ android:drawable:指定截取Drawable对象。
@ android:clipOrientation:指定截取方向,可设置水平截取或垂直截取。
@ android:gravity:指定攫取时的对其方式。

使用ClipDrawable对象时可调用setLevel(int level)来设置攫取的区域大小,当level为0时,
截取的图片片段为空;当level为10000时,截取整张图片。

范例:徐徐展开的图片
因为ClipDrawable对象可调用setLevel(int level)控制截取图片的部分,因此只要设置一个定时器,让程序不断
调用ClipDrawable的setLevel(int level)即可实现图片徐徐展开的效果。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <ImageView
        android:id="@+id/image"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:scaleType="fitStart"
        android:src="@drawable/my_clip" />
</LinearLayout>
<?xml version="1.0" encoding="UTF-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android" 
    android:drawable="@drawable/shuangta" 
    android:clipOrientation="horizontal" 
    android:gravity="center"> 
</clip>

程序先定义一个ClipDrawable对象对象,上面的程序控制从中间开始截取图片,截取方向为水平截取。
接下来程序将通过一个定时器来定期修改ClipDrawable对象的level,即可实现图片徐徐张开的效果。

 1 public class ClipDrawableTest extends Activity {   
 3     private ClipDrawable drawable = null;
 4     
 5     final Handler handler = new Handler() {
 6         @Override
 7         public void handleMessage(Message msg) {
 8             // 如果该消息是本程序所发送的
 9             if (msg.what == 0x1233) {
10                 // 修改ClipDrawable的level值
11                 drawable.setLevel(drawable.getLevel() + 200);
12             }
13         }
14     };
15     
16     @Override
17     public void onCreate(Bundle savedInstanceState) {
18         super.onCreate(savedInstanceState);
19         setContentView(R.layout.main);
20         ImageView imageview = (ImageView) findViewById(R.id.image);
21         // 获取图片所显示的ClipDrawable对象
22         drawable = (ClipDrawable) imageview.getDrawable();
23         
24         final Timer timer = new Timer();
25         timer.schedule(new TimerTask() {
26             @Override
27             public void run() {
28                 Message msg = new Message();
29                 msg.what = 0x1233;
30                 // 发送消息,通知应用修改ClipDrawable对象的level值。
31                 handler.sendMessage(msg);
32                 // 取消定时器
33                 if (drawable.getLevel() >= 10000) {
34                     timer.cancel();
35                 }
36             }
37         }, 0, 300);
38     }
39 }

【AnimationDrawable】
Android既支持传统的帧动画(电影方式,一张张切换),也支持通过平移、变换计算出来的补间动画。

定义补间动画的XML资源文件以<set.../>元素作为根元素,该元素内可以指定如下4个元素:
@ alpha:设置透明度的改变。
@ scale:设置图片进行缩放改变。
@ translate:设置图片进行位移变换。
@ rotate:设置图片进行旋转。

定义动画的XML资源应该放在/res/anim路径下。

定义补间动画的思路很简单:设置一张图片的开始状态(透明度、位置、缩放比、旋转度)、并设置该图片
的结束状态(透明度、位置、缩放比、旋转度),再设置动画的持续时间,Android系统会使用动画效果把这
张图片从开始状态变换到结束状态。

设置补间动画的语法格式如下:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@[package:]anim/interpolator_resource"
    android:shareInterpolator=["true" | "false"]
    android:duration="持续时间">
    <alpha
        android:fromAlpha="float"
        android:toAlpha="float" />
    <scale
        android:fromXScale="float"
        android:toXScale="float"
        android:fromYScale="float"
        android:toYScale="float"
        android:pivotX="float"
        android:pivotY="float" />
    <translate
        android:fromXDelta="float"
        android:toXDelta="float"
        android:fromYDelta="float"
        android:toYDelta="float" />
    <rotate
        android:fromDegrees="float"
        android:toDegrees="float"
        android:pivotX="float"
        android:pivotY="float" />
    <set>
        ...
    </set>
</set>

fromXxx,toXxx:这些属性就用于定义图片的开始状态、结束状态。
除此之外 scale缩放变化, rotate旋转变换 时,还需要指定如下
pivotX、pivotY两个属性。这两个属性用于指定变换的"中心点"
---比如进行旋转变换时,需要指定"旋轴点";进行缩放变换时,
需要指定"中心点"。

上面<set.../>、<alpha.../>、<scale.../>、<translate.../>、<rotate.../>都可指定一个
android:interpolator属性,该属性指定动画的变化速度,可以实现匀速、正速度、负速度、
无规则变加速等,Android系统的R.anim类中包含了大致常量,它们定义了不同的动画速度。
例如:
linear_interpolator:匀速变换。
accelerate_interpolator:加速变换。
decelerate_interpolator:减速变换。
如果程序想让<set.../>元素下所有的变换效果使用相同的动画速度,则可指定
android:shareInterpolator="true"。

<?xml version="1.0" encoding="UTF-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/linear_interpolator"
    android:duration="5000">
    <!-- 定义缩放变换 -->
    <scale android:fromXScale="1.0"  
        android:toXScale="1.4"  
        android:fromYScale="1.0"  
        android:toYScale="0.6"  
        android:pivotX="50%" 
        android:pivotY="50%" 
        android:fillAfter="true" 
        android:duration="2000" /> 
    <!-- 定义位移变换 -->        
    <translate android:fromXDelta="10"
        android:toXDelta="130"
        android:fromYDelta="30"
        android:toYDelta="-80"
        android:duration="2000" />
</set>

为了在Java代码中获取实际的Animation对象,则可调用AnimationUtils方法如下:
loadAnimation(Context ctx, int resId)

 1 public class AnimationDrawable extends Activity {
 2     @Override
 3     public void onCreate(Bundle savedInstanceState) {
 4         super.onCreate(savedInstanceState);
 5         setContentView(R.layout.main);
 6         final ImageView image = (ImageView) findViewById(R.id.image);
 7         // 加载动画资源
 8         final Animation anim = AnimationUtils.loadAnimation(this,
 9                 R.anim.my_anim);
10         // 设置动画结束后保留结束状态
11         anim.setFillAfter(true);
12         Button bn = (Button) findViewById(R.id.bn);
13         bn.setOnClickListener(new OnClickListener() {
14             @Override
15             public void onClick(View arg0) {
16                 // 开始动画
17                 image.startAnimation(anim);
18             }
19         });
20     }
21 }

 

6.5 属性动画(Property Animation)资源
Animator代表一个属性动画,但它只是一个抽象类,通常会使用它的子类:AnimatorSet、ValueAnimator、ObjectAnimator、
TimeAnimator。

定义属性动画的XML资源文件能以如下三个元素中的任意一个作为根元素。
@ <set.../>:它是一个父元素,用于包含其他<objectAnimator.../>、<animator.../>或<set.../>子元素,
该元素定义的资源代表AnimatorSet对象。
@ <objectAnimator.../>:用于定义ObjectAnimator动画。
@ <animator.../>:用于定义ValueAnimator动画。

定义属性动画的语法格式如下:

<set
  android:ordering=["together" | "sequentially"]>
    <objectAnimator
        android:propertyName="string"
        android:duration="int"
        android:valueFrom="float | int | color"
        android:valueTo="float | int | color"
        android:startOffset="int"
        android:repeatCount="int"
        android:repeatMode=["repeat" | "reverse"]
        android:valueType=["intType" | "floatType"]/>
    <animator
        android:duration="int"
        android:valueFrom="float | int | color"
        android:valueTo="float | int | color"
        android:startOffset="int"
        android:repeatCount="int"
        android:repeatMode=["repeat" | "reverse"]
        android:valueType=["intType" | "floatType"]/>
    <set>
        ...
    </set>
</set>

范例:不断渐变的背景色(使用属性动画来控制组件背景色不断渐变)
R.animator.color_anim

 

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:propertyName="backgroundColor"
    android:duration="3000"
    android:valueFrom="#FF8080"
    android:valueTo="#8080FF"
    android:repeatCount="infinite"
    android:repeatMode="reverse"
    android:valueType="intType">
</objectAnimator>

 

AnimatorTest.java 类文件

public class AnimatorTest extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        LinearLayout container = (LinearLayout) findViewById(R.id.container);
        // 添加MyAnimationView组件
        container.addView(new MyAnimationView(this));
    }

    public class MyAnimationView extends View {
        public MyAnimationView(Context context) {
            super(context);
            // 加载动画资源
            ObjectAnimator colorAnim = (ObjectAnimator) AnimatorInflater
                    .loadAnimator(AnimatorTest.this, R.animator.color_anim);
            colorAnim.setEvaluator(new ArgbEvaluator());
            // 对该View本身应用属性动画
            colorAnim.setTarget(this);
            // 开始指定动画
            colorAnim.start();
        }
    }
}

 

6.6 使用原始XML资源
6.7 使用布局(Layout)资源
6.8 使用菜单(Menu)资源

 

6.9 样式(Style)和主题(Theme)资源

一个样式相当于多个格式的集合,其他UI组件通过style属性来指定样式,这就相当于把该样式包含的所有格式
同时应用于该UI组件。
Android的样式资源文件放在/res/values目录下,样式资源文件的跟元素是<resources.../>元素,该元素内可
包含过个<style.../>子元素,每个<style.../>元素定义一个样式。

<style.../>元素指定如下两个属性:
name:指定样式的名称。
parent:指定该样式所继承的父样式。当继承某个父样式时,该样式将会获得父样式中定义的全部格式。
          当然,当前样式也可以覆盖父样式中指定的格式。

my_style.xml

 

 

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <resources>
 3     <!-- 定义一个样式,指定字体大小、字体颜色 -->
 4     <style name="style1"> 
 5         <item name="android:textSize">20sp</item> 
 6         <item name="android:textColor">#00d</item> 
 7     </style>
 8     <!-- 定义一个样式,继承前一个颜色 -->
 9     <style name="style2" parent="@style/style1"> 
10         <item name="android:background">#ee6</item>
11         <item name="android:padding">8dp</item>
12         <!-- 覆盖父样式中指定的属性 -->
13         <item name="android:textColor">#000</item>
14     </style>
15     <style name="CrazyTheme">
16         <item name="android:windowNoTitle">true</item>
17         <item name="android:windowFullscreen">true</item>        
18         <item name="android:windowFrame">@drawable/window_border</item>
19         <item name="android:windowBackground">@drawable/star</item>
20     </style>    
21 </resources>

 

main.xml

 

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <!-- 指定使用style1的样式 -->
    <EditText
        style="@style/style1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/style1" />
    <!-- 指定使用style2的样式 -->
    <EditText
        style="@style/style2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/style2" />
</LinearLayout>

 

与样式资源非常相似,主题资源的XML文件通常也放在/res/values目录下。主题资源的XML文档同样以<resource.../>元素
作为跟元素,同样使用<style.../>元素来定义主题。

与样式的区别主要体现在:
1)主题不能作用与单个的View组件,主体应该对整个应用中的所有Activity起作用,或对指定的Activity起作用。
2)主题定义的格式应该是改变窗口外观的格式,例如窗口标题、窗口边框等。

范例:给所有的窗口添加边框、背景(图6.10)
为了给所有窗口都添加边框、背景,先在/res/values/my_style.xml文件中增加一个主题,
定义主体的<style.../>片段如下:

 

<style name="CrazyTheme">
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowFullscreen">true</item>        
        <item name="android:windowFrame">@drawable/window_border</item>
        <item name="android:windowBackground">@drawable/star</item>
</style>

其中@drawable/star是一张图片;@drawable/window_border是一个ShapeDrawable资源。

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <!-- 设置填充颜色 -->
    <solid android:color="#0fff"/>
    <!-- 设置四周的内边距 -->
    <padding android:left="7dp" 
        android:top="7dp" 
        android:right="7dp" 
        android:bottom="7dp" />
    <!-- 设置边框 -->
    <stroke android:width="10dip" android:color="#f00" />
</shape>

定义了上面的主题之后,接下来即可在Java代码中使用该主题,例如如下代码:
在onCreate中调用,setTheme(R.style.CrazyTheme);

大部分时候,在AndroidManifest.xml文件中对指定应用、指定Activity应用主题更加简单。
如果我们想让应用中全部窗口使用该主题,只要为<application.../>元素添加android:theme属性。
属性值是一个主题的名字,如下所示:

<application android:theme="@style/CrazyitTheme">
...
</application>

Android中提供了几种内置的主题资源,这些主题通过查询Android.R.style类可以看到。例如前面介绍的对话框
风格的窗口,我们只要采用如下代码来定义某个Activity即可。

<activity android:theme="@android:style/Theme.Dialog">
...
</activity>

与样式类似的是,Android主题同样支持继承。如果开发过程中还想利用某个主题。但需要对它进行局部修改,
则可通过继承系统主题来实现自定义主题,例如如下代码片段:

<style name="CrazyTheme" parent="@android:style/Theme.Dialog">
...</activity>

6.10 属性(Attribute)资源

 

/res/values/attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- 定义一个属性 -->
    <attr name="duration"></attr>
    <!-- 定义一个styleable对象来组合多个属性 -->
    <declare-styleable name="AlphaImageView">
        <attr name="duration"/>
    </declare-styleable>
</resources>

【提示】在属性资源中定义<declare-styleable.../>元素时,也可在其内部直接使用<attr.../>定义属性,
使用<attr../>时指定一个format属性即可,例如上面我们可以指定<attr name="duration" format="integer"/>。

 1 public class AlphaImageView extends ImageView {
 2     // 图像透明度每次改变的大小
 3     private int alphaDelta = 0;
 4     // 记录图片当前的透明度。
 5     private int curAlpha = 0;
 6     // 每隔多少毫秒透明度改变一次
 7     private final int SPEED = 300;
 8     Handler handler = new Handler() {
 9         @Override
10         public void handleMessage(Message msg) {
11             if (msg.what == 0x123) {
12                 // 每次增加curAlpha的值
13                 curAlpha += alphaDelta;
14                 if (curAlpha > 255)
15                     curAlpha = 255;
16                 // 修改该ImageView的透明度
17                 AlphaImageView.this.setAlpha(curAlpha);
18             }
19         }
20     };
21 
22     public AlphaImageView(Context context, AttributeSet attrs) {
23         super(context, attrs);
24         TypedArray typedArray = context.obtainStyledAttributes(attrs,
25                 R.styleable.AlphaImageView);
26         // 获取duration参数
27         int duration = typedArray
28                 .getInt(R.styleable.AlphaImageView_duration, 0);
29         // 计算图像透明度每次改变的大小
30         alphaDelta = 255 * SPEED / duration;
31     }
32 
33     @Override
34     protected void onDraw(Canvas canvas) {
35         this.setAlpha(curAlpha);
36         super.onDraw(canvas);
37         final Timer timer = new Timer();
38         // 按固定间隔发送消息,通知系统改变图片的透明度
39         timer.schedule(new TimerTask() {
40             @Override
41             public void run() {
42                 Message msg = new Message();
43                 msg.what = 0x123;
44                 if (curAlpha >= 255) {
45                     timer.cancel();
46                 } else {
47                     handler.sendMessage(msg);
48                 }
49             }
50         }, 0, SPEED);
51     }
52 }

代码中的R.styleable.AlphaImageView、R.styleable.AlphaImageView_duration都是Android SDK根据
属性资源文件自动生成的。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:crazyit="http://schemas.android.com/apk/res/org.crazyit.res"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <!-- 使用自定义组件,并指定属性资源中定义的属性 -->
    <org.crazyit.res.AlphaImageView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:src="@drawable/ee"
        crazyit:duration="60000" />
</LinearLayout>

crazyit:duration助兴位于“http://schemas.android.com/apk/res/ + 项目包名”命名空间下。

6.11 使用原始资源
AssetManager是一个专门管理/assets/目录下原始资源的管理器类,AssetManager提供了如下两个常用方法来访问Asset资源。
inputStream open(String fileName):根据文件名来获取原始资源对应的输入流。
AssetFileDescriptor openFd(String fileName):根据文件名来获取原始资源对应的AssetFileDescriptor。
AssetFileDescriptor代表了一项原始资源的描述,应用程序可通过AssetFileDescriptor来获取原始资源。

 1 public class RawResTest extends Activity {
 2     MediaPlayer mediaRaw = null;    // 播放raw声音
 3     MediaPlayer mediaAsset = null;  // 播放asset声音
 4 
 5     @Override
 6     public void onCreate(Bundle savedInstanceState) {
 7         super.onCreate(savedInstanceState);
 8         setContentView(R.layout.main);
 9         // 直接根据声音文件的ID来创建MediaPlayer。
10         mediaRaw = MediaPlayer.create(this, R.raw.bomb);
11         // 获取该应用的AssetManager
12         AssetManager am = getAssets();
13         try {
14             // 获取指定文件对应的AssetFileDescriptor。
15             AssetFileDescriptor afd = am.openFd("shot.mp3");
16             mediaAsset = new MediaPlayer();
17             // 使用MediaPlayer加载指定的声音文件。
18             mediaAsset.setDataSource(afd.getFileDescriptor());
19             mediaAsset.prepare();
20         } catch (IOException e) {
21             e.printStackTrace();
22         }
23         // 获取第一个按钮,并为它绑定事件监听器
24         Button playRaw = (Button) findViewById(R.id.playRaw);
25         playRaw.setOnClickListener(new OnClickListener() {
26             @Override
27             public void onClick(View arg0) {
28                 // 播放声音
29                 mediaRaw.start();
30             }
31         });
32         // 获取第二个按钮,并为它绑定事件监听器
33         Button playAsset = (Button) findViewById(R.id.playAsset);
34         playAsset.setOnClickListener(new OnClickListener() {
35             @Override
36             public void onClick(View arg0) {
37                 // 播放声音
38                 mediaAsset.start();
39             }
40         });
41     }
42 }

6.12 国际化和资源自适应
国际化的英文单词是Internationalization,简称I18N,其中I第一个字母,18中间省略的字母个数。
而N代表最后一个字母。

图6.12 Java程序国际化的思路

Java程序的国际化主要通过如下三个类完成:
& java.util.ResourceBundle:用于加载一个国家、语言资源包。
& java.util.Locale:用于封装一个特定的国家/区域、语言环境。
& java.text.MessageFormat:用于格式化带占位符的字符串。

为了实现程序的国际化,必须先提供程序所需的资源文件。资源文件的内容适合很多key-value对。其中key是程序
使用的部分,而value则是程序界面的显示字符串。

资源文件的命名可以有如下三种形式:
& baseName_language_country.properties
& baseName_language.properties
& baseName.properties
其中baseName是资源文件的基本名,用户可以自由定义。
language和country都不可以随意变化,必须是Java所支持的语言和国家。

【Java支持语言和国家】
事实上,Java不可能支持所有的国家和语言,如需获取Java所支持的语言和国家,可调用Locale类的getAvailableLocales方法获取,
该方法返回一个Locale数组,该数组里包含了Java所支持的语言和国家。

public class TestDemo9 {
    public static void main(String[] args) {
        // 返回Java所支持的全部国家和语言的数组
        Locale[] localeList = Locale.getAvailableLocales();
        // 遍历数组的每个元素,依次获取所支持的国家和语言
        for (int i=0; i<localeList.length; i++) {
            System.out.println(localeList[i].getDisplayCountry()
            + "=" + localeList[i].getCountry()
            + "=" + localeList[i].getDisplayLanguage()
            + "=" + localeList[i].getLanguage());
        }
    }
}

输出结果:
日本=JP=日文=ja
秘鲁=PE=西班牙文=es
==英文=en
日本=JP=日文=ja
巴拿马=PA=西班牙文=es
波斯尼亚和黑山共和国=BA=塞尔维亚文=sr
==马其顿文=mk
危地马拉=GT=西班牙文=es
阿拉伯联合酋长国=AE=阿拉伯文=ar
挪威=NO=挪威文=no
阿尔巴尼亚=AL=阿尔巴尼亚文=sq
==保加利亚文=bg
伊拉克=IQ=阿拉伯文=ar
也门=YE=阿拉伯文=ar
==匈牙利文=hu
葡萄牙=PT=葡萄牙文=pt
塞浦路斯=CY=希腊文=el
卡塔尔=QA=阿拉伯文=ar
马其顿王国=MK=马其顿文=mk
==瑞典文=sv
瑞士=CH=德文=de
美国=US=英文=en
芬兰=FI=芬兰文=fi
==冰岛文=is
==捷克文=cs
马耳他=MT=英文=en
斯洛文尼亚=SI=斯洛文尼亚文=sl
斯洛伐克=SK=斯洛伐克文=sk
==意大利文=it
土耳其=TR=土耳其文=tr
==中文=zh
==泰文=th
沙特阿拉伯=SA=阿拉伯文=ar
==挪威文=no
英国=GB=英文=en
塞尔维亚及黑山=CS=塞尔维亚文=sr
==立陶宛文=lt
==罗马尼亚文=ro
新西兰=NZ=英文=en
挪威=NO=挪威文=no
立陶宛=LT=立陶宛文=lt
尼加拉瓜=NI=西班牙文=es
==荷兰文=nl
爱尔兰=IE=爱尔兰文=ga
比利时=BE=法文=fr
西班牙=ES=西班牙文=es
黎巴嫩=LB=阿拉伯文=ar
==朝鲜文=ko
加拿大=CA=法文=fr
爱沙尼亚=EE=爱沙尼亚文=et
科威特=KW=阿拉伯文=ar
塞尔维亚=RS=塞尔维亚文=sr
美国=US=西班牙文=es
墨西哥=MX=西班牙文=es
苏丹=SD=阿拉伯文=ar
印度尼西亚=ID=印度尼西亚文=in
==俄文=ru
==拉托维亚文(列托)=lv
乌拉圭=UY=西班牙文=es
拉脱维亚=LV=拉托维亚文(列托)=lv
==希伯来文=iw
巴西=BR=葡萄牙文=pt
叙利亚=SY=阿拉伯文=ar
==克罗地亚文=hr
==爱沙尼亚文=et
多米尼加共和国=DO=西班牙文=es
瑞士=CH=法文=fr
印度=IN=印地文=hi
委内瑞拉=VE=西班牙文=es
巴林=BH=阿拉伯文=ar
菲律宾=PH=英文=en
突尼斯=TN=阿拉伯文=ar
==芬兰文=fi
奥地利=AT=德文=de
==西班牙文=es
荷兰=NL=荷兰文=nl
厄瓜多尔=EC=西班牙文=es
台湾地区=TW=中文=zh
约旦=JO=阿拉伯文=ar
==白俄罗斯文=be
冰岛=IS=冰岛文=is
哥伦比亚=CO=西班牙文=es
哥斯达黎加=CR=西班牙文=es
智利=CL=西班牙文=es
埃及=EG=阿拉伯文=ar
南非=ZA=英文=en
泰国=TH=泰文=th
希腊=GR=希腊文=el
意大利=IT=意大利文=it
==加泰罗尼亚文=ca
匈牙利=HU=匈牙利文=hu
==法文=fr
爱尔兰=IE=英文=en
乌克兰=UA=乌克兰文=uk
波兰=PL=波兰文=pl
卢森堡=LU=法文=fr
比利时=BE=荷兰文=nl
印度=IN=英文=en
西班牙=ES=加泰罗尼亚文=ca
摩洛哥=MA=阿拉伯文=ar
玻利维亚=BO=西班牙文=es
澳大利亚=AU=英文=en
==塞尔维亚文=sr
新加坡=SG=中文=zh
==葡萄牙文=pt
==乌克兰文=uk
萨尔瓦多=SV=西班牙文=es
俄罗斯=RU=俄文=ru
韩国=KR=朝鲜文=ko
==越南文=vi
阿尔及利亚=DZ=阿拉伯文=ar
越南=VN=越南文=vi
黑山=ME=塞尔维亚文=sr
==阿尔巴尼亚文=sq
利比亚=LY=阿拉伯文=ar
==阿拉伯文=ar
中国=CN=中文=zh
白俄罗斯=BY=白俄罗斯文=be
香港=HK=中文=zh
==日文=ja
以色列=IL=希伯来文=iw
保加利亚=BG=保加利亚文=bg
==印度尼西亚文=in
马耳他=MT=马耳他文=mt
巴拉圭=PY=西班牙文=es
==斯洛文尼亚文=sl
法国=FR=法文=fr
捷克共和国=CZ=捷克文=cs
瑞士=CH=意大利文=it
罗马尼亚=RO=罗马尼亚文=ro
波多黎哥=PR=西班牙文=es
加拿大=CA=英文=en
德国=DE=德文=de
==爱尔兰文=ga
卢森堡=LU=德文=de
==德文=de
阿根廷=AR=西班牙文=es
==斯洛伐克文=sk
马来西亚=MY=马来文=ms
克罗地亚=HR=克罗地亚文=hr
新加坡=SG=英文=en
==丹麦文=da
==马耳他文=mt
==波兰文=pl
阿曼=OM=阿拉伯文=ar
==土耳其文=tr
泰国=TH=泰文=th
==希腊文=el
==马来文=ms
瑞典=SE=瑞典文=sv
丹麦=DK=丹麦文=da
洪都拉斯=HN=西班牙文=es

【为Android应用提供国际化资源】
不同values文件夹的命名方式为:values-语言代码-r 国家代码。
例如:values-zh-rCN、values-en-rUS。

【提示】如果还需要为drawable目录按分辨率提供文件夹,则可以在后面追加分辨率后缀,
例如drawable-zh-rCN-mdpi、drawable-zh-rCN-hdpi、drawable-zh-rCN-xhdpi、
drawable-en-rUS-mdpi、drawable-en-rUS-hdpi、drawable-en-rUS-xhdpi等。

6.13 自适应不同屏幕的资源
Android默认把drawable目录分别drawable-ldpi、drawable-mdpi、drawable-hdpi、drawable-xhdpi。

通常来说,屏幕资源需要考虑如下两个方面:
屏幕尺寸:可分为small(小屏幕)、normal(中等屏幕)、large(大屏幕)、xlarge(超大屏幕)。
屏幕分辨率:可分为ldpi(低分辨率)、mdpi(中等分辨率)、hdpi(高分辨率)、xhdpi(超高分辨率)4中。
屏幕方向:分为 land(横屏)和port(竖屏)两种。

下面是上面4中屏幕尺寸所需的最低分辨率:
● xlarge 屏幕尺寸至少需要 960dp*720dp。
● large 屏幕尺寸至少需要 640dp*480dp。
● normal 屏幕尺寸至少需要 470dp*320dp。
● small 屏幕尺寸至少需要 426dp*320dp。

为了提供自适应不同屏幕的资源,最简单的做法就是为不同屏幕尺寸、不同屏幕分辨率提供相应的布局资源、Drawable资源。
● 屏幕分辨率:可以为drawable目录增加如下后缀,ldpi(低分辨率),mdpi(中等分辨率),hdpi(高分辨率),
xhdpi(超高分辨率),nodpi(默认分辨率)。分别为不同不分辨率的屏幕提供资源。
● 屏幕尺寸:可以为layout、values等目录增加如下后缀:small, normal, large, xlarge,
分别为不同尺寸的屏幕提供相应资源。
● 屏幕方向:可以为layout、values等目录增加后缀land和port,分别为横屏,竖屏提供相应的资源。

 

posted on 2015-07-01 13:34  大米稀饭  阅读(601)  评论(0)    收藏  举报