Android字符串资源

(转载)http://blog.csdn.net/hanyingjie327/article/details/19331557

有三种类型的字符串资源:

String:XML资源文件定义一个单独的字符串。
String Array XML资源文件定义一个字符串数组。
Quantity Strings (Plurals)XML资源文件定义一定数量的字符串集合。
所有的字符串资源都可以使用样式标记(styling markup)和格式化参数(formatting arguments)。


String

String资源XML文件中定义的单独的字符串可以被应用或其他的xml文件中引用。
文件存放路径: res/values/ filename .xml。文件名可以任意命名。
资源引用:
在Java文件中: R.string.string_name。
         可以通过  getString(int)或者 getText(int)方法取得字符串资源。
 CharSequence getText(int resId):返回本地、样式化的字符。
 String getString(int resId) :
返回不带格式的字符串。
                  例如: String string = getString(R.string.stringName);
在XML资源文件中: @string/string_name
语法:
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.     <string name="string_name">text_string</string>  
  4. </resources>  
<resources>节点必须有,而且必须是根节点,没有属性。
<string>节点的值可以包括样式化标记,注意如果字符串值包括单引号或双引号字符,必须转义。
XML文件中的单引号或双引号:
        可以用“\”转义符转义单引号或双引号;
        如果内容中有单引号,用双引号括起来,不用转义符也可以,例如:<string name="single_quoted_string"> "single quoted'string"</string>;
如果内容中有单引号,如果不转义符转义或者双引号括起来的话,编译会报错;
        如果内容中有双引号,不能用单引号括起来(编译会报错),如果不用转义符,取值时双引号会被忽略。

做个实际例子测试一下:
       res/values/strings.xml文件中添加:
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <!-- 测试字符串资源 -->  
  2. <string name="simple_string">simple string</string>  
  3.       
  4. <string name="single_quoted_string">"single quoted'string"</string>  
  5. <!-- <string name="str">single quoted'string</string> 该行编译时会报错:error: Apostrophe not preceded by \ (in single quoted'string) -->  
  6. <string name="single_quoted_string2">single quoted\'string</string>  
  7.       
  8. <string name="double_quoted_string">\"double quotes\"</string>  
  9. <string name="double_quoted_string2">"double quotes"</string>  
  10. <!--     <string name="str3">'"double quotes"'</string> 该行编译会报错-->  
     定义几个Button按钮,一个TextView控件用来显示结果,java主要代码:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. StringBuffer sbf = new StringBuffer();  
  2. String simple_string = getString(R.string.simple_string);  
  3. sbf.append("getString(simple_string):" + simple_string + "\n");  
  4.   
  5. String single_quoted_string = getString(R.string.single_quoted_string);  
  6. sbf.append("getString(single_quoted_string):" + single_quoted_string + "\n");  
  7.   
  8. String single_quoted_string2 = getString(R.string.single_quoted_string2);  
  9. sbf.append("getString(single_quoted_string2):" + single_quoted_string2 + "\n");  
  10.   
  11. String double_quoted_string = getString(R.string.double_quoted_string);  
  12. sbf.append("getString(double_quoted_string):" + double_quoted_string + "\n");  
  13.   
  14. String double_quoted_string2 = getString(R.string.double_quoted_string2);  
  15. sbf.append("getString(double_quoted_string):" + double_quoted_string2 + "\n");  
  16.   
  17. tv.setText(sbf.toString());  
执行结果:



String Array

文件存放路径: res/values/ filename .xml。文件名可以任意命名。
在Java文件中引用: R.array. string_array_name。
Resources res = getResources();
String[] stringArray = res.getStringArray(R.array.string_array_name);
语法:
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.     <string-array name="string_array_name">  
  4.         <item>text_string</item>  
  5.     </string-array>  
  6. </resources>  
<item>节点:可以包含样式化格式的字符串。它的值可以是另外一个字符串资源,注意如果字符串值包括单引号或双引号字符,必须转义。
XML文件中的单引号或双引号处理,参考上一部分的解释。
还是做个实际例子测试一下:
       res/values/strings.xml文件中添加:
     
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1.  <!-- To support arrays -->  
  2. <string-array name="test_array">  
  3.     <item>one</item>  
  4.     <item>two</item>  
  5.     <item>three</item>  
  6.     <item>@string/simple_string</item>  <!-- 引用其他stirng资源,上面定义过的string -->  
  7.     <item>"single quoted'string"</item>  
  8.     <item>single quoted\'string</item>  
  9.     <item>\"double quotes\"</item>  
  10.     <item>"double quotes"</item>  
  11. </string-array>  
java主要代码:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. StringBuffer sbf = new StringBuffer();  
  2. Resources res = getResources();  
  3. String[] stringArray = res.getStringArray(R.array.test_array);  
  4. for (String str : stringArray) {  
  5.     sbf.append(str);  
  6.     sbf.append("\n");  
  7. }  
  8. tv.setText(sbf.toString());  
执行结果:


Quantity Strings (Plurals)

不同的语言对于数量有不同的语法规则。例如,在英语中,数量1是一种特殊的情况,被写做1 book,但是其他的数量要被写成n book。这是非常普通的单/复数之间的区分,而其他的语言会有更细的区分。Android支持的完整设置如下:zeroonetwofewmanyother

用给定的语言和数量来判断使用哪一种规则是非常复杂的,因此Android提供了一些方法,来为应用程序选择合适的资源,如getQuantityString()方法。

要注意的是,选择是基于语言语法的必要性。在英语中对于数量设置为zero的字符串,即使是数量为0也会被忽略,因为0数量在语法上除了1以外,与其他数量没有区别(zero booksone booktwo books等等)。不要被表面现象所误导,要根据实际的语言语法差异来进行区分。

通常要尽可能的使用中性的数量描述来避免语言语法的差异,如“Books1”。如果在应用程序中保持这种风格,这将使处理语言语法上的差异变得更加容易。

文件存放路径: res/values/ filename .xml 文件名可以任意命名。
在Java文件中引用: R.plurals. plural_name
语法:
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.     <plurals  
  4.         name="plural_name">  
  5.         <item quantity=["zero" | "one" | "two" | "few" | "many" | "other"]>text_string</item>  
  6.     </plurals>  
  7. </resources>  

quatity 属性:它是一个关键词,用于指示该字符串所使用的时机。有效值与简单的例子如下:

说明
zero当语言中需要对数量词0进行特殊处理时,要使用这个设置(如阿拉伯语)
one当语言中需要对像1这样的数量词进行特殊处理时,要使用这个设置(如英语和许多其他的语言)
two当语言中需要对像2这样的数量词进行特殊处理时,要使用这个设置(如威尔士语的2或斯洛文尼亚语的102)
few当语言中需要对小的数量词进行特殊处理时,要使用这个设置。(如捷克语中带有234的数量词;或是波兰语中以234结尾但不是121314的数量词。)
many当语言中需要对大的数量词进行特殊处理时,要使用这个设置。(如马耳他语中以11---99之间的数字结尾的数量词。)
other当语言中不需要对给定的数量进行特殊处理时,使用这个设置。(例如中文或英语中的42)

Java代码中的用法如下:

int count = getNumberOfsongsAvailable();
Resources res getResources();
String songsFound = res.getQuantityString(R.plurals.numberOfSongsAvailable,count, count);

当使用getQuantityString()方法时,如果字符串中包含了带有数字的字符串格式,就需要传递count参数两次。例如,对于字符串“%d songs found”,第一个count参数会选择合适的复数字符串,第二个参数会插入到%d位置。如果复数字符串不包含格式化字符,就不需要传递第三个参数给getQuantityString()方法。

这个和多语言有关系,自己理解的也不是很清楚,例子不写了。



字符串的格式化和样式化(Formatting and Styling)

以下是如何正确的格式化和样式化字符串资源的一些注意的事情:

 转义单引号和双引号(Escaping apostrophes and quotes)

如果在字符中有单引号或双引号,那么既可以通过转义字符转义,也可以把整个字符串封闭在其他类型的封闭引号内。例如,以下字符串资源的定义后两个会导致在某些场合下不能够工作:

<stringname="good_example">"This'll work"</string>
<stringname="good_example_2">This\'ll also work</string>
<stringname="bad_example">This doesn't work</string>
<stringname="bad_example_2">XML encodings don&apos;t work</string>

XML文件中的单引号或双引号总结:

        可以用“\”转义符转义单引号或双引号;
        如果内容中有单引号,用双引号括起来,不用转义符也可以,例如:<string name="single_quoted_string"> "single quoted'string"</string>;
如果内容中有单引号,如果不转义符转义或者双引号括起来的话,编译会报错;
        如果内容中有双引号,不能用单引号括起来(编译会报错),如果不用转义符,取值时双引号会被忽略。

格式化字符串(Formatting strings)

如果需要格式化字符串资源,可以把格式化参数放在字符串资源中,然后调用   String.format(String, Object...)方法取值,例如:

<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
在这个例子中,格式化字符串有两个参数: %1$s 代表一个字符串, %2$d 代表一个十进制的数字。在代码中使用如下方法来替换资源定义中的格式化字符串:

Resources res = getResources();
String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);

除了$s和$d外,还有其他的一些数据类型,可以查一下Java字符串格式化的资料。

做个实际例子测试一下:
      res/values/strings.xml文件中添加:

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <string name="format_string">  
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. Hello, I am %2$d years old, My name is %1$s.  
  2. lt;/string>  
java主要代码:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. String format_string = getString(R.string.format_string, "Superman"20);  
执行结果:


带HTML标记的字符串(Styling with HTML markup)

使用如下方法,可以给XML中的字符串资源添加样式:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="welcome">Welcome to <b>Android</b>!</string>
</resources>
Android 支持的 HTML 元素包括:

  • <b> : 加粗(bold).
  • <i> :斜体(italic).
  • <u> :下划线underline).
不同的控件显示可能支持更多的HTML标签,例如TextView支持<br>、<h1>等更多的HTML标签。

在XML文件中定义带HTML标签的String,大概可以用以下3中方式:


第一种HTML标签定义方式:

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <string name="tagged_string1">  
  2.     <b>Bold</b><i>italic</i><u>underline</u>.  
  3. </string>  

下面我们测试一下这种方式如何使用:

1、我们通过getString()方法取得字符串然后设置为TextView的内容:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. String tagged_string = getString(R.string.tagged_string1);  
  2. tv.setText(tagged_string);  
运行结果:


HTML标签没有起作用。

2、调用Html.fromHtml()方法转化一下:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. String tagged_string = getString(R.string.tagged_string1);  
  2. tv.setText(Html.fromHtml(tagged_string));  
执行结果:

HTML标签任然没有起作用。

3、调用一下我们前面提到的getText()方法:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. tv.setText(getText(R.string.tagged_string1));  

HTML标签起了作用。

4、在其他的资源中通过ID引用:
我们定义一个Button,Button的Text设置为我们上面定义的String(ID为tagged_string1):

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <Button   
  2.         android:layout_width="wrap_content"  
  3.         android:layout_height="wrap_content"  
  4.         android:text="@string/tagged_string1"  
  5.  />  
看一下运行效果:

第一种HTML标签定义方式总结:

通过getString()方法获取字符串无HTML效果;

通过getText()方法获取字符串有HTML效果;

在其他资源定义时通过ID引用该字符串有HTML效果。


第二种HTML标签定义方式,通过"&lt;"转义"<"符号

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <string name="tagged_string2">  
  2.        &lt;b>Bold&lt;/b>, &lt;i>italic&lt;/i>, &lt;u>underline&lt;/u>.  
  3. </string>  

下面我们测试一下第二种方式如何使用:

1、我们通过getString()方法取得字符串然后设置为TextView的内容:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. String tagged_string = getString(R.string.tagged_string2);  
  2. tv.setText(tagged_string);  
运行结果:


HTML标签没有起作用,只是把HTML标签当成了字符串的内容取出来。

2、调用Html.fromHtml()方法转化一下:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. String tagged_string = getString(R.string.tagged_string2);  
  2. tv.setText(Html.fromHtml(tagged_string));  
执行结果:

HTML标签起作用。

3、调用一下我们前面提到的getText()方法:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. tv.setText(getText(R.string.tagged_string2));  

HTML标签没有起作用,只是把HTML标签当成了字符串的内容取出来。

4、在其他的资源中通过ID引用:
我们定义一个Button,Button的Text设置为我们上面定义的String(ID为tagged_string1):

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <Button   
  2.         android:layout_width="wrap_content"  
  3.         android:layout_height="wrap_content"  
  4.         android:text="@string/tagged_string2"  
  5.  />  
看一下运行效果:

第二种HTML标签定义方式总结:

通过getString()方法获取字符串无HTML效果;

通过getString()方法获取字符串,然后调用Html.fromHtml()转化一下,有HTML效果;

通过getText()方法获取字符串无HTML效果;

在其他资源定义时通过ID引用该字符串无HTML效果。


第三种HTML标签定义方式,通过"CDATA"区段,使XML解析器忽略其中的节点标签:

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <string name="tagged_string3">  
  2.       <![CDATA[  
  3.             <b>Bold</b>, <i>italic</i>, <u>underline</u>. 
  4.             <br/> 
  5.             <h1>font</h1> 
  6.       ]]>  
  7. </string>  

下面我们测试一下第三种方式如何使用:

1、我们通过getString()方法取得字符串然后设置为TextView的内容:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. String tagged_string = getString(R.string.tagged_string3);  
  2. tv.setText(tagged_string);  
运行结果:


HTML标签没有起作用,只是把HTML标签当成了字符串的内容取出来。

2、调用Html.fromHtml()方法转化一下:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. String tagged_string = getString(R.string.tagged_string3);  
  2. tv.setText(Html.fromHtml(tagged_string));  

执行结果:


HTML标签起作用。

3、调用一下我们前面提到的getText()方法:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. tv.setText(getText(R.string.tagged_string3));  

执行结果:


HTML标签没有起作用,只是把HTML标签当成了字符串的内容取出来。

4、在其他的资源中通过ID引用:
我们定义一个Button,Button的Text设置为我们上面定义的String(ID为tagged_string1):

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <Button   
  2.         android:layout_width="wrap_content"  
  3.         android:layout_height="wrap_content"  
  4.         android:text="@string/tagged_string3"  
  5.  />  

看一下运行效果:


总结:第三种HTML标签定义方式,只是在定义时和第二种有所区别,一个是通过转义"<"字符,一个通过CDATA区段,调用方式相同。


用HTML标记以及格式化字符串

如果创建一个添加了样式的文本,同时还要使用格式化字符串。通常这样做是不会工作的,因为String.format()方法会去掉字符串中的所有样式信息。因此要围绕HTML标签进行字符转义工作,然后再格式化处理之后,调用fromHtml(String)方法来获取字符串资源,
还是用例子测试,xml文件中增加:
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <string name="format_tagged_string">Hello, %1$s! You have &lt;b>%2$d new messages&lt;/b>.</string>  
上面用了"&lt;"转义"<"字符,或者用CDATA区段,效果一样:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <string name="format_tagged_string">  
  2. <![CDATA[   
  3.             Hello, %1$s! You have <b>%2$d new messages</b>.  
  4. ]]>  
  5. </string>  



java代码:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. String tagged_string = getString(R.string.format_tagged_string);  
  2. tv.setText(String.format(tagged_string, "superman"25));  
运行结果:
String.format()方法过滤掉了字符串中的样式信息。

所以在调用format()方法后,还得调用一下   fromHtml(String)方法把HTML文本转换成样式文本,java代码改为:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. String tagged_string = getString(R.string.format_tagged_string);  
  2. String formatStr = String.format(tagged_string, "superman"25);  
  3. tv.setText(Html.fromHtml(formatStr));  
运行结果:

HTML标签起了作用。

因为fromHtml(String)方法会格式化所有的HTML标签,所以对于包含HTML标记的特殊文本,必须调用htmlEncode(String)方法,确保其中的任何HTML字符都被转义。例如,如果传递给String.format()的字符串参数中包含了诸如”<”或”&”等符号,那么它们在被格式化之前,必须被转义,以便在格式化之后的字符被传递给fromHtml(String)方法时,被转换成初始编写的样子。
java代码改一下,传递的参数值有"<"特殊字符:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. String tagged_string = getString(R.string.format_tagged_string);  
  2. String formatStr = String.format(tagged_string, "superman <"25);  
  3. tv.setText(Html.fromHtml(formatStr));  
执行结果:
可以看出由于特殊字符的原因,丢掉了一些内容。

调用一下htmlEncode(string)方法,java代码改为:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. String escapedUsername = TextUtils.htmlEncode("superman <");  
  2. String tagged_string = getString(R.string.format_tagged_string);  
  3. String formatStr = String.format(tagged_string, escapedUsername, 25);  
  4. tv.setText(Html.fromHtml(formatStr));  
执行结果:

结果正确,特殊字符被转义了。


最后附上测试Demo的源码: String资源Demo源码


官方原文:http://developer.android.com/guide/topics/resources/string-resource.html

参考:http://www.cnblogs.com/hnrainll/archive/2012/11/21/2781121.html

http://blog.csdn.NET/think_soft/article/details/7518824



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值