10.3 字符串(String)资源

字符串是最常用的资源,在创建Android工程时ADT会默认生成一些字符串资源。这些字符串资源将被作为默认的应用程序名称和窗口标题使用。Android SDK除了支持普通的字符串资源,还支持字符串数组和复数字符串资源,并且可以利用占位符格式化字符串。字符串资源(包括普通字符串、字符串数组和复数字符串)需要在res/values目录中的xml文件中定义(任何一个文件都可以)。本节将详细介绍各种字符串资源的使用方法。

10.3.1 普通字符串

普通字符串资源使用<string>标签定义,示例代码如下:

<?xml version="1.0" encoding="utf-8"?>

<resources>

  <!-- hello就是一个字符串资源,name属性值“hello”是字符串资源的key,通过这个key

      可以引用字符串资源的值(Hello!) -->

  <string name="hello">Hello!</string>

</resources>

在布局文件中使用字符串资源的代码如下:

<TextView

  android:layout_width="fill_parent"

  android:layout_height="wrap_content"

  android:text="@string/hello" />

在代码中使用字符串资源的代码如下:

String str = getResources().getString(R.string.hello);

10.3.2 字符串数组

字符串数组资源由<string-array>标签定义,在<string-array>标签中包含的若干<item>标签表示字符串数组元素。例如,下面的代码定义了一个包含4个元素的字符串数组。

<?xml version="1.0" encoding="utf-8"?>

<resources>

  <string-array name="planets_array">

    <item>Mercury</item>

    <item>Venus</item>

    <item>Earth</item>

    <item>Mars</item>

  </string-array>

</resources>

在布局文件中使用字符串数组资源的代码如下:

<CustomWidget

  android:layout_width="fill_parent"

  android:layout_height="wrap_content"

  android:array_text="@array/planets_array" />

在代码中引用字符串数组的代码如下:

Resources res = getResources();

// planets数组的长度为4,正好是planets_array字符串数组资源中定义的4个<item>标签中的值

String[] planets = res.getStringArray(R.array.planets_array);

注意

不能用字符串数组资源设置接收字符串的属性,例如,android:text,因为这样系统会直接将字符串数组资源的ID值当做文本传给该属性。应该用字符串资源设置那些可以接收字符串数组资源的属性。例如,CustomWidget是一个自定义控件,android:array_text是一个自定义的属性,可以接收字符串数组资源。

10.3.3 复数字符串

在某些自然语言中不同的数字在使用方法上会有所不同。例如,在英文中,如果说一本书,会说one book,如果说两本书,会说two books。当数量大于1时,会在名词后面加s或变成其他复数形式(不可数名词和专属名词除外),在这种情况下就需要考虑不同数字的字符串资源。

复数字符串资源为这种情况提供了解决方案。需要用<plurals>标签定义复数字符串,并使用<item>标签指定具体处理哪一类数字的复数字符串。现在来看一个例子。

<?xml version="1.0" encoding="utf-8"?>

<resources>

  <!- 定义复数资源 -->

  <plurals name="numberOfSongsAvailable">

    <item quantity="one">One song found.</item>

    <!-- 指定了一个参数(%d),使用other资源使需要传递一个整数 -->

    <item quantity="other">%d songs found.</item>

  </plurals>

</resources>

其中quantity属性的值除了one和other外,还可以是zero、two、few和many。

使用复数字符串资源可以使用getQuantityString方法,该方法有两个重载形式,它们的原型如下:

public String getQuantityString(int id, int quantity) throws NotFoundException;

public String getQuantityString(int id, int quantity, Object... formatArgs)

                                 throws NotFoundException;

其中id参数表示复数字符串资源的ID,quantity参数表示具体的数字,例如,1对应quantity属性值的“one”,2对应quantity属性值的“two”。formatArgs参数表示复数字符串资源的参数。

引用复数字符串的Java代码如下:

// 引用数字为1的复数字符串资源

setTitle(getResources().getQuantityString(

        R.plurals.numberOfSongsAvailable, 1));

// 引用数字为other的复数字符串资源,调用时向other资源传递一个参数值(20)

setTitle(getResources().getQuantityString(

        R.plurals.numberOfSongsAvailable, 20, 20));

10.3.4 在字符串中使用引号

字符串中的值虽然可以任意指定,但遇到特殊符号时,如双引号、单引号,就需要采取特殊的方法进行处理。

如果是单引号('),可以使用转意符(\)或用双引号(")将整个字符串括起来。如果是双引号,可以在双引号前使用转意符(\)。下面的代码演示了如何处理带单引号和双引号的字符串资源。

<!-- 输出This'll work -->

<string name="str1">"This'll work"</string>

<!-- 输出This 'll also work -->

<string name="str2">This\'ll also work</string>

<!—输出"apple" -->

<string name="str3">\"apple\"</string>

10.3.5 用占位符格式化字符串

String.format(String, Object...)方法可以格式化带占位符的字符串。因此,只要在字符串资源中插入占位符就可以使用String.format方法格式化字符串资源。format方法要求占位符用%1、%2、……%n表示。其中第n个占位符与format方法的n+1个参数值对应。

带占位符的字符串资源

<!-- $s表示该占位符要求传入字符串,$d表示该占位符要求传入整数 -->

<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>

格式化字符串资源的Java代码:

Resources res = getResources();

String text = String.format(res.getString(R.string.welcome_messages),"lining",18);

10.3.6 用HTML标签格式化字符串资源

字符串资源支持一些HTML标签,因此,可以直接在字符串资源中使用这些HTML标签格式化字符串。

用HTML标签格式化的字符串资源

<?xml version="1.0" encoding="utf-8"?>

<resources>

  <string name="welcome">Welcome to <b>Android</b>!</string>

</resources>

字符串资源支持如下的HTML标签。

<b>:粗体字。

<i>:斜体字。

<u>:带下划线的文字。

有时需要同时使用HTML标签和占位符格式化字符串,但使用String.format方法格式字符串,会忽略字符串中所有的HTML标签。为了使format方法可以格式化带HTML标签的字符,需要使用Html.fromHTML方法先处理一下字符串。下面来看一个完整的例子。

同时包含HTML标签和占位符的字符串资源:

<resources> <string name="welcome_messages">Hello, %1$s! You have <b>%2$d new messages</b>. </string></resources>

注意

由于需要使用Html.fromHTML方法处理字符串,因此,HTML标签中的“<“需要使用“<”表示(“>”可以直接使用)。

使用字符串资源的Java代码:

Resources res = getResources();

String text = String.format(res.getString(R.string.welcome_messages), "lining", 20);

CharSequence styledText = Html.fromHtml(text);

如果format的某个参数值包含HTML的特殊字符,如“<”、“&”,可以使用下面的代码先格式化这个参数值,再使用format方法格式化字符串。

// username中包含HTML的特殊字符

String escapedUsername = TextUtil.htmlEncode(username);

Resources res = getResources();

String text = String.format(res.getString(R.string.welcome_messages), escapedUsername, mailCount);

CharSequence styledText = Html.fromHtml(text);