Android 支持的资源
一 资源文件的命名
1 资源文件和资源文件中key不能使用中文命名,
2 多个资源文件和key也要遵循唯一的原则,也就是同类型的文件名或key 不能重复.例如两个表示字符串资源的key不能重复,就算这两个 key 在不同的 XML 文件中也不行
3 不能存在文件名相同、扩展名不同的资源文件,例如在res\drawable 目录下不能同时放置icon.jpg 和 icon.png文件
二 关于使用系统资源
Android SDK 提供了大量的系统资源,可以在<Android SDK安装目录>\platforms\android-2.1(或其他版本)\data\res 目录中找到这些资源
使用系统资源的写法是:
在Java类中android.R.resourceType.resourceId , 其中resourceType 可以是string, drawable.color
在XML文件中 例如android:text="@android:string/selectAll"
下面具体讲解各类型的资源文件
1 字符串资源(string)文件 定义字符串资源的XML文件可以任意命名
无论字符串资源放在res\values 目录下的哪个资源文件中,在生成ID时都会放在R.string 类中。这就意味着,字符串资源的 key 的唯一性的作用域是res\values 目录中所有的资源文件
在资源文件中不能直接使用"<" 、"&"等特殊符号,但可以使用">"、"/"等符号,要使用这些特殊符号就要使用 HTML 实体符号表示,如"<" 的实体符号是"<", "&" 的实体符号是"&"
注意以下写法
<string name="tagged_string">
<h1><font color='#0000FF'>测试<font/><h1/>
</string>
2 数组(array)资源 数组资源包括字符串数组和整数数组资源
字符串数组资源使用 <string-array> 标签定义, 整数数组资源使用<integer-array> 标签定义
注意如果使用<string-array> 定义整数数组,通过getIntArray 方法读取数组元素值时会返回0; 如果使用<integer-array> 定义字符串数组,ADT会显示无法验证通过
(1). 无论字符串资源放在 res\values 目录下哪个资源文件中,在生成 ID 时都会放在 R.string 类中。 这就意味着,字符串资源的 key 的唯一性的作用域是 res\values 目录中所有的资源文件。
(2) 在字符串资源中不能直接使用像“<h1>...</h1>”的HTML 标签,也不能使用< 和&等特殊符号,但可以使用 > 和 /, 要使用< ,必须用实体符号, 如< 对应 < , &对应&
例如以下写法: <string name="tagged_string">
<h1><font color="#0000FF">测试<font/><h1/>
</string>
(3) 也可以直接在字符串资源中使用 “<”、“&”等字符,但要放在<![CDATA[...]]>, 例如:
<string name="tagged1_string">
<![CDATA[<a href='http://www.baidu.com'>http://www.baidu.com</a>]]>
</string>
在Java 类中调用如下:
String tag = getString(R.string.tagged1_string);
tvTag.setText(Html.fromHtml(tagged1));
3. 数组 (Array) 资源
分为字符串数组和整数数组,分别由<string-array>, <integer-array>标签定义.
<string-array> 和 <integer-array> 标签只能分别定义字符串数组和整数数组。如果使用<string-array> 定义整数数组,通过getIntArray 方法读取数组元素值进会返回0; 使用<integer-array> 标签则只允许数组元素的值是整数。如果违反这个规则, ADT 会显示无法验证通过.
4 颜色(color) 资源
颜色值支持如下4种表示方式
#RGB
#ARGB
#RRGGBB
#AARRGGBB
其中R、G、B表示三原色,也就是红、绿蓝,A表示透明度,也就是Alpha值。A、R、G、B的取值范围都是0~255,R、G、B的取值越大,颜色越深。如果R、G、B都等于0,表示的颜色是黑色,都是255, 表示的颜色是白色.R、G、B三个值相等时表示灰度值。R、G、B总共可表示16777216(2^8 *2^8*2^8)种颜色。
A取0时表示完全透明,255时表示不透明.如果采用前两种颜色值表示法,A、R、G、B 的取值是0~15, 这并不意味着颜色范围的256个值的前15个,而是将每一个值扩展成两位,例如#F00 相当于#FF0000; #A567 相当于#AA556677.由此可以看出,#RGB 和 #ARGB 可设置的颜色值并不多,它们的限制条件是颜色值和透明度的8位字节的高4位和低4位相同.
看一个示例 ch13_color 工程
color.xml 文件定义:
<resources>
<!-- 红色 -->
<color name="red_color">#F00</color>
<!--蓝色-->
<color name="blue_color">#0000FF</color>
<!--半透明绿色-->
<color name="green_color">#5000FF00</color>
<!--白色-->
<color name="white_color">#5FFF</color>
</resources>
示意图
5 尺寸(dimension) 资源 尺寸资源是一系列的浮点数组成的资源
一个示例 dimens.xml
<resources>
<dimen name="size_px">50px</dimen>
<dimen name="size_in">1.5in</dimen>
<dimen name="size_sp">30sp</dimen>
</resources>
Android 支持以下6 种度量单位
(1) px: 表示屏幕实际的像素 320 * 480 表示屏幕横向有320 个像素,480 个像素
(2) in: 表示英寸,指屏幕的物理尺寸,1 in = 2.54cm
(3) mm: 表示毫米,是屏幕的物理尺寸
(4) pt: 表示一个点,是屏幕的物理尺寸,大小为1英寸的 1/72
(5) dp: 与密度无关的像素,这是一个基于屏幕物理密度的抽象单位。密度可以理解为每英寸包含的像素点个数(单位是dpi),1dp 实际上相当于密度为160dpi的屏幕的一个点.也就是说,如果屏幕的物理密度是160dpi时,dp和px是等效的。一块拥有320 * 480 分辨率手机屏幕,如果宽度是2in,高度是3 in,这块屏幕的密度是160dpi.如果屏幕大小未变,而分辨率发生了变化, 例如 ,分辨率由 320 * 480 变成了480 * 480,这时屏幕的物理密度就变大了(大于160dpi), 这就意味着屏幕每英寸可以显示更多的像素点,屏幕的显示效果就更细腻了。
假设一个按钮的宽度使用dp作为单位,在160dpi时设为160,而在更高的dpi下(如320dpi), 按钮宽度看上去和160dpi 时的屏幕一样,这是由于系统在发现屏幕的密度不是 160dpi时,会计算一个转换比例,然后用这个比例与实际设置的尺寸相乘就得出新的尺寸。计算比例的方法是目标屏幕的密度除以 160.如果目标屏幕的密度是 320dpi, 那么这个比例就是 2,如果按钮的宽度是 160dp,那么在320dpi的屏幕上的宽度就是320个像素点(dp 是抽象单位,在实际的屏幕上应转换成像素点)。由引可以看出,dp可以自适应屏幕的密度。不管屏幕密度怎样变化,只要屏幕的物理尺寸不变,实际显示的尺寸就不会变化。如果将按钮的宽度设成160px,那么在 320dpi的屏幕上仍然会是160个像素点,看上去按钮宽度只是160dpi 屏幕的一半。Android系统建议设置表示宽度、高度、位置等属性时应尽量使用dp作为尺寸单位。除了使用dp,也可以使用dip,它们是等效的。要注意,dpi 表示密度,另外 dip = dp
(6) sp: 与比例无关的像素. 这个单位与dp类似。但除了自适应屏幕密度外,还会自适应用户设置的字体。Android 系统推荐在设置字体大小尽量使用sp作为尺寸单位
dimens.xml资源两种应用方式是: android:layout_height="@dimen/size_px" ,float size_in = getResources().getDimension(R.dimen.size_in);
6 类型(Style) 资源, 具体示例代码请参见 ch13_styles 工程
之所以要创建style.xml 资源,是因为, 虽然XML布局文件中可以灵活地设置组件的属性,但如果有很多组件的属性都需要设置同一个值,就需要类型(style)资源
使用步骤
(1) 定义style.xml文件
<resources>
<style name="style1">
<item name="android:textSize">20sp</item>
<item name="android:textColor">#FFFF00</item>
</style>
</resources>
(2) 在组件标签中使用style
<TextView android:layout_width="fill_parent" adnroid:layout_height="wrap_content" android:text="style1" style="@style/style1" />
要注意 style前面不能加android 命名空间
7 主题(Theme)资源
打开<Android 安装目录>\platform\android-1.5\data\res\values\themes.xml 文件,可以看到 主题也是类型,只是这种类型只能用于<activity> 和<application>标签,在<activity> 中使用主题可以覆盖<application>的主题,具体示例代码请参见ch13_themes 工程
8 图片(Drawable) 资源, Android 系统支持很多常用的图片格式,如png,jpg,bmp,git(不支持动画gif)
Android 系统还支持一种绘制颜色的 Drawable 资源,这种资源需要在res\values 目录中的资源文件中配置。一段示例代码如下:
<resources>
<drawable name="solid_blue">#0000FF</drawable>
<drawable name="solid_yellow">#FFFF00</drawable>
<color name="solid_blue">#0000FF</color>
<color name="solid_yellow">#FFFF00</color>
</resources>
在XML布局文件中可以直接使用@drawable/resourceID 来指定这些资源
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="drawable"
android:textColor="@drawable/solid_yellow" android:background="@drawable/solid_blue" android:layout_marginTop="200dp"/>
在Java类中写法: Drawable drawable = getResources().getDrawable(R.drawable.solid_blue);
虽然在读取图像文件和绘制颜色的Drawable 资源时都返回家Drawable 对象,但实际指向Drawable 对象.普通的图像指向 BitmapDrawable 对象;9.patch图像指向NinePatchDrawable 对象,绘制颜色的 Drawable 资源指向PaintDrawable 对象
9 动画(Animation)资源,动画资源文件放在res\anim目录中
10 菜单(menu) 资源, 菜单资源必须放在res\menu 目录中
先看一个 选项菜单 的写法
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/mnuFestival" android:title="节日"
android:icon="@drawable/festival" />
<group android:id="@+id/mnuFunction">
<item android:id="@+id/mnuEdit" android:title="编辑" android:icon="@drawable/edit" />
<item android:id="@+id/mnuDelete" android:title="删除"
android:icon="@drawable/delete" />
<item android:id="@+id/mnuFinish" android:title="完成"
android:icon="@drawable/finish" />
</group>
<item android:id="@+id/mnuOthers" android:title="其他功能">
<menu>
<group android:checkableBehavior="single">
<item android:id="@+id/mnuDiary" android:title="日记"
android:menuCategory="system" android:checked="true" />
<item android:id="@+id/mnuAudio" android:title="音频"
android:orderInCategory="2" />
<item android:id="@+id/mnuVideo" android:title="视频"
android:orderInCategory="3" />
</group>
</menu>
</item>
</menu>
可参见一个示例ch13_menu 工程
11 布局(Layout) 资源
12 属性(Attribute) 资源,相当重要 android系统的属性配置文件放在<Android SDK 安装目录>\platforms\android-8(或其他版本)\data\res\values\attrs.xml
属性资源放在res\values 目录中,文件名可以任意取(并不限定于attrs.xml).限定性一个属性值的基本语法如下:
<attr name="属性名" format="属性值限定字符串" />
format 属性值 必须是指定的限定字符串, 如reference、string、float、color等
如果有很多组件都使用 有同样限定的属性,可以单独使用<attr> 标签定义这些属性,然而再对其引用. 为了在自定义组件中读取属性值,需要将 <attr> 标签放到<declare-styleable>标签中,该标签只有一个 name 属性,用于引用定义的类型.
下面代码是一个示例:
<resources>
<attr name="iconSrc" format="reference" />
<declare-styleable name="MyWidget">
<attr name="id" />
</declare-styleable>
</resources>
从上面代码在 <declare-styleable> 标签中引用事先定义好的属性并不需要指定 format 值,这也有利于减少重复的配置代码.
一个示例 请参见 ch13_icontextview 工程
本示例实现一个自定义的 IconTextView 组件, 可以在文本的前面/后面显示一个图标,组件有一个自定义属性iconSrc, 但只在java类中对该属性的值进行验证.主要代码有:
第一部分 : <resources>
<!--定义一个全局的属性及其属性值约束,然后只需引用该属性的的属性名-->
<attr name="iconPosition">
<enum name="left" value="0" />
<enum name="right" value="1" />
</attr>
<declare-styleable name="IconTextView">
<attr name="iconSrc" format="reference" />
<!--只需简单地使用attr 标签引用iconPosition -->
<attr name="iconPosition" />
</declare-styleable>
</resources>
第二部分: 在IconTextView 类的构造方法中,读取iconSrc 和 iconPosition 属性的值, 代码如下:
public IconTextView(Context context, AttributeSet attrs) {
super(context, attrs);
//1. 定义表示属性数组的对象 typeArray, 也就是<declare-styleable> 标签对应的对象,
// 依上述,取得name属性值, 一般该属性值可设为与组件类相同的名字,
TypedArray typedArray = context.obtainStyledAttributes(attrs,
R.styleable.IconTextView);
// 2. 获取具体的属性值要使用 TypeArray 类的 getResourceId, getInt等,
// 相应的资源ID 名称是<declare-styleable> 标签的 name 属性值与相应的<attr> 标签的name属性值的组合,用_ 分隔
resourceId = typedArray.getResourceId(R.styleable.IconTextView_iconSrc, 0);
if (resourceId > 0)
bitmap = BitmapFactory.decodeResource(getResources(), resourceId);
iconPosition = typedArray.getInt(R.styleable.IconTextView_iconPosition,0);
}
第三部分: 在使用IconTextView 组件前,需要先在布局文件中定义命名空间,如下
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/com.test.mobile"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
......
其中app 命名空间的com.test.mobile 是R类的包名,不能设为其他值.
第四部分: 使用IconTextView 组件的代码
<com.test.mobile.widget.IconTextView
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:text="第一个笑脸" app:iconSrc="@drawable/small" app:iconPosition="left" />
运行示例,示意图如下
----------------------------------------------
13 xml 资源, 必须放在res\xml 目录中,可以通过Resources.getXml 方法获得处理指定XML 文件的 XmlResourceParse 对象,
XML 资源实际上就是 XML 格式的文本文件,这些文件必须放在 res\xml 目录中,可以通过 Resource.getXml 方法获得处理指定 XML 文件的 XmlResourceParser 对象, XmlResourceParser 对象处理XML 文件通过调用 next 方法不断更新当前的状态
具体代码请参见 ch13_xml工程。
14 RAW 资源 ,放在res\raw 目录下,通过Resources.openRawResource() 获得读取指定文件的 InputStream 对象
例如 InputStream is = getResources().openRawResources(R.raw.test);
15 Assets 资源,放在 assets 目录下,ADT 在建立Android 工程时会自动建立该目录, 这就意味着所有放在 assets 目录中的资源文件都不会生成资源 ID, 因此
在读取这些资源文件时需要直接使用资源文件内容. 一段示例如下:
try
{
InputStream is = getAssets().open("test/test.txt");
byte[] buffer = new byte[1024];
int count = is.read(buffer);
String s = new String(buffer, 0 , count);
textView.setText(s);
}
catch (Exception e)
{ }
要注意: open 方法的参数表示 assets 资源文件名,路径是相对 assets 目录的,以上代码表示在assets目录下有test 目录,在这个 test 目录下有 test.txt 文件。
用斜杠 (/) 表示路径,否则不能找到 test.txt 文件。
具体代码请参见 ch13_assets 工程