Android资源文件中保存字符串数组详解

资源文件中保存字符串数组

大家都知道在android工程的/res/values文件夹中有一个strings.xml,可以用来记录代码和布局文件中需要用到的字符串资源。但strings.xml中记录的字符串都是彼此独立,没有关系的,获取时也只能根据名称一个个的获取。如果有多个相关的字符串需要记录在一起,也就是记录字符串数组,该如何实现呢?
一种方法是将多个字符串用一个分隔符(例如;)拼接在一起,在代码中通过getString()获取到字符串后,再通过String.split()将其分割成字符串数组。这种方法的缺点是很明显的。

  • 字符串太长,维护困难
  • 容易出现重复或遗漏
  • 对每个字符串的含义缺少说明

事实上android sdk本身已经支持字符串数组的资源类型,允许直接在资源文件中保存字符串数组。使用方法如下。

  1. 在/res/values文件夹下新建arrays.xml
    Android开发时习惯上将一种类型的资源保存在一个单独的文件中,在创建一个android工程时会默认在/res/values文件夹中生成4个文件,分别用来保存4种类型的资源(strings.xml字符串资源;Color.xml颜色资源;dimens.xml数值资源;styles.xml样式资源),但并没有生成用来保存字符串数组的资源文件,所以需要新建一个资源文件来保存字符串数组,通常将其命名为arrays.xml。当然,也可以根据需要将其命名为任意文件名(android在解析资源文件时,资源的类型只取决于xml中节点的名称,和资源文件名没有任何关系,事实上完全可以在strings.xml中定义颜色资源,在Color.xml中定义字符串资源,也可以将所有的资源都定义在一个文件中,但最好还是按照习惯来,每种类型资源保存在对应的资源文件中)。
  2. 在arrays.xml中创建资源节点
    和其他资源文件结构相同,arrays.xml中最外层为resources节点,内部为string-array节点。举例如下。

    <resources>
        <string-array name="fruit_price">
            <item>1.5</item>
            <item>2.3</item>
            <item>5.8</item>
        </string-array>
    </resources>

使用资源文件中保存的字符串数组

在布局文件中使用字符串数组资源

在布局文件中可以通过@array/资源id来访问一个字符串数组资源。例如ListView,Spinner中都可以在布局文件中设置android:entries属性,来指定一个字符串数组资源作为其默认显示的列表内容。

在代码中使用字符串数组资源

在Activity中可以通过getResources().getStringArray(id)方法来获取一个字符串数组资源id对应的字符串数组。如果找不到该id对应的资源,会抛出android.content.res.Resources$NotFoundException,如果能够找到该id对应的资源,但该字符串数组没有配置任何item,则会返回length为0的String数组。

为字符串数组资源增加描述

如果字符串数组资源中保存的不是有明确含义的字符串,在使用时就很容易弄混。可以为每一个item增加描述,记录每个字符串的含义。
为字符串数组资源增加描述的方法是为每一个item增加一个属性,属性名可以任意取,在属性值中填入对应的描述。android在解析xml时会自动忽略那些不认识的属性,所以这个描述属性只对维护xml文件的人有用,对程序运行没有任何影响。例如:

<resources>
    <string-array name="fruit_price">
        <item description="apple">1.5</item>
        <item description="pear">2.3</item>
        <item description="banana">5.8</item>
    </string-array>
</resources>

格式化字符串问题

Android不允许在资源文件中直接保存有多个格式化字符(即%*)的字符串,例如"The name is %s and the count is %d"(但只有一个格式化字符是可以的,例如"The name is %s")。所以如果字符串数组中某些字符串中有格式化字符,那么是不能直接写在xml文件中的。
解决方法是,如果字符串里的%确实用作格式化字符串使用,那么可以在%后面加上一个数字和$符号,第一个%后面的数字为1,后面每个%后面的数字是前面的%后面的数字加1,例如,"The name is %1$s, the count is %2$d and the size is %3$f"。如果%不是作为格式化字符串使用,而是作为普通字符使用,那么可以为资源增加formatted="false"属性。例如:

<resources>
    <string-array name="fruit_price" formatted="false">
        <item description="apple">苹果价格为%d元每%s</item>
        <item description="pear">梨价格为%d元每%s</item>
        <item description="banana">香蕉价格为%d元每%s</item>
    </string-array>
</resources>

注意:formatted="false"属性只能加在字符串数组所在的资源id节点上,不能加在item节点上。为字符串数组添加formatted="false"属性后,数组中所有的字符串在解析时%都将其作为普通字符来解析,无法为字符串数组中每个字符串单独设置formatted属性(加在item节点上的formatted属性是无效的)。

<!--无效的写法-->
<resources>
    <string-array name="fruit_price">
        <item description="apple" formatted="false">苹果价格为%d元每%s</item>
        <item description="pear" formatted="false">梨价格为%d元每%s</item>
        <item description="banana" formatted="false">香蕉价格为%d元每%s</item>
    </string-array>
</resources>

连字号-的warning问题

当字符串数组资源文件中保存的字符串中包含连字号-(数字0右边的字符)的时候,会出现一个warning,warning内容为"Replace "-" with an "en dash" character (–, &&;#8211;) ?",意思是android建议用en dash替换字符串中的-。连字号-的英文是hyphen,在显示效果上en dash要比hyphen稍长,因此android建议用en dash代替-,以便有更好的显示效果。关于en dash和hyphen的详细区别参见http://www.zhihu.com/question/20332423和https://en.wikipedia.org/wiki/Dash。
如果包含连字号的字符串只用在显示的时候使用,那么可以采用warning中给出的建议,即用”–” (不含双引号)来代替连字号-。如果包含连字号的字符串会被用作其他用途,例如字符串比较,搜索,正则匹配,URL地址等,就不能对连字号进行替换。
解决方法是屏蔽这个warning,在资源文件的最外层resources节点增加xmlns:tools=”http://schemas.android.com/tools”属性,然后在需要屏蔽这个warning的字符串对应的item增加tools:ignore="TypographyDashes"属性。例如:

<resources xmlns:tools="http://schemas.android.com/tools">
    <string-array name="phone_number">
        <item description="lili" tools:ignore="TypographyDashes">0551-25332991</item>
    </string-array>
</resources>

如果要屏蔽字符串数组中所有项的连字号warning,可以在字符数组对应的节点增加tools:ignore="TypographyDashes"属性,例如:

<resources xmlns:tools="http://schemas.android.com/tools">
    <string-array name="phone_number" tools:ignore="TypographyDashes">
        <item description="lili">0551-25332991</item>
    </string-array>
</resources>

如果要屏蔽整个资源文件中所有字符串的连字号warning,可以在字符数组对应的节点增加tools:ignore="TypographyDashes"属性,例如:

<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="TypographyDashes">
    <string-array name="phone_number">
        <item description="lili">0551-25332991</item>
    </string-array>
</resources>

屏蔽单个字符串的连字号warning的另一个方法是将字符串用 <![CDATA[ ]]>包围起来,例如:

<resources>
    <string-array name="phone_number">
        <item description="lili"><![CDATA[0551-25332991]]></item>
    </string-array>
</resources>

你可能感兴趣的:(android,字符串资源,arrays-xml)