一、 字符串资源概述:
有三种类型的字符串资源:String、String Array和Quantity Strings(Plurals); 所有的字符串资源都可以使用样式标记(styling markup)和格式化参数(formatting arguments)。
二、 字符串资源的三种类型:
1. String资源XML文件中定义的单独的字符串可以被应用或其他的xml文件中引用。
文件存放路径:res/values/filename.xml。文件名可以任意命名。在Java文件中:R.string.string_name。可以通过 getString(int)或者getText(int)方法取得字符串资源。
CharSequence getText(int resId):返回本地、样式化的字符。String getString(int resId) :返回不带格式的字符串。在XML资源文件中:@string/string_name
语法:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="string_name">text_string</string>
</resources>
<resources>节点必须有,而且必须是根节点,没有属性。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="string_name">text_string</string>
</resources>
<string>节点的值可以包括样式化标记,注意如果字符串值包括单引号或双引号字符,必须转义。
XML文件中的单引号或双引号:可以用“\”转义符转义单引号或双引号;如果内容中有单引号,用双引号括起来,不用转义符也可以;如果内容中有单引号,如果不转义符转义或者双引号括起来的话,编译会报错;如果内容中有双引号,不能用单引号括起来(编译会报错),如果不用转义符,取值时双引号会被忽略。
2. String Array:
文件存放路径:res/values/filename.xml。文件名可以任意命名。
在Java文件中引用:R.array.string_array_name。
Resources res = getResources();
String[] stringArray = res.getStringArray(R.array.string_array_name);
3. Quantity Strings(Plurals):
不同的语言对于数量有不同的语法规则。例如,在英语中,数量1是一种特殊的情况,被写做1 book,但是其他的数量要被写成n book。这是非常普通的单/复数之间的区分,而其他的语言会有更细的区分。Android支持的完整设置如下:zero、one、two、few、many和other。
用给定的语言和数量来判断使用哪一种规则是非常复杂的,因此Android提供了一些方法,来为应用程序选择合适的资源,如getQuantityString()方法。
要注意的是,选择是基于语言语法的必要性。在英语中对于数量设置为zero的字符串,即使是数量为0也会被忽略,因为0数量在语法上除了1以外,与其他数量没有区别(zero books、one book、two books等等)。不要被表面现象所误导,要根据实际的语言语法差异来进行区分。
通常要尽可能的使用中性的数量描述来避免语言语法的差异,如“Books:1”。如果在应用程序中保持这种风格,这将使处理语言语法上的差异变得更加容易。
文件存放路径:res/values/filename.xml。文件名可以任意命名。
在Java文件中引用:R.plurals.plural_name。
语法:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<plurals
name="plural_name">
<item quantity=["zero" | "one" | "two" | "few" | "many" | "other"]>text_string</item>
</plurals>
</resources>
quatity 属性:它是一个关键词,用于指示该字符串所使用的时机。有效值与简单的例子如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<plurals
name="plural_name">
<item quantity=["zero" | "one" | "two" | "few" | "many" | "other"]>text_string</item>
</plurals>
</resources>
值 | 说明 | ||
zero | 当语言中需要对数量词0进行特殊处理时,要使用这个设置(如阿拉伯语) |
| |
one | 当语言中需要对像1这样的数量词进行特殊处理时,要使用这个设置(如英语和许多其他的语言) |
| |
two | 当语言中需要对像2这样的数量词进行特殊处理时,要使用这个设置(如威尔士语的2或斯洛文尼亚语的102) |
| |
few | 当语言中需要对小的数量词进行特殊处理时,要使用这个设置。(如捷克语中带有2、3和4的数量词;或是波兰语中以2、3、4结尾但不是12、13、14的数量词。) |
| |
many | 当语言中需要对大的数量词进行特殊处理时,要使用这个设置。(如马耳他语中以11---99之间的数字结尾的数量词。) |
| |
other | 当语言中不需要对给定的数量进行特殊处理时,使用这个设置。(例如中文或英语中的42) |
|
Java代码中的用法如下:
int count = 15;
String songsFound = getResources().getQuantityString(R.plurals.numberOfSongsAvailable,count, count);
当使用getQuantityString()方法时,如果字符串中包含了带有数字的字符串格式,就需要传递count参数两次。例如,对于字符串“%d songs found”,第一个count参数会选择合适的复数字符串,第二个参数会插入到%d位置。如果复数字符串不包含格式化字符,就不需要传递第三个参数给getQuantityString()方法。
三、 字符串的格式化和样式化(Formatting and Styling)
1. 转义单引号和双引号(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't work</string>
2. 格式化字符串(Formatting strings):
如果需要格式化字符串资源,可以把格式化参数放在字符串资源中,然后调用 String.format(String, Object...)方法取值,例如:
<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
在这个例子中,格式化字符串有两个参数:%1$s代表一个字符串,%2$d代表一个十进制的数字。在代码中使用如下方法来替换资源定义中的格式化字符串:
String text=String.format(getResources().
getString(R.string.welcome_messages), username, mailCount);
3. 带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标签定义方式:
<string name="tagged_string1">
<b>Bold</b>, <i>italic</i>, <u>underline</u>.
</string>
<string name="tagged_string1">
<b>Bold</b>, <i>italic</i>, <u>underline</u>.
</string>
1、我们通过getString()方法取得字符串然后设置为TextView的内容:
String tagged_string = getString(R.string.tagged_string1);
tv.setText(tagged_string);
String tagged_string = getString(R.string.tagged_string1);
tv.setText(tagged_string);
运行结果:
2、调用Html.fromHtml()方法转化一下:
String tagged_string = getString(R.string.tagged_string1);
tv.setText(Html.fromHtml(tagged_string));
String tagged_string = getString(R.string.tagged_string1);
tv.setText(Html.fromHtml(tagged_string));
执行结果:
3、调用一下我们前面提到的getText()方法:
tv.setText(getText(R.string.tagged_string1));
执行结果:
tv.setText(getText(R.string.tagged_string1));
4、在其他的资源中通过ID引用:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tagged_string1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tagged_string1"
/>
看一下运行效果:
第一种HTML标签定义方式总结:
通过getString()方法获取字符串无HTML效果;
通过getText()方法获取字符串有HTML效果;
在其他资源定义时通过ID引用该字符串有HTML效果。
第二种HTML标签定义方式,通过"<"转义"<"符号:
<string name="tagged_string2">
<b>Bold</b>, <i>italic</i>, <u>underline</u>.
</string>
<string name="tagged_string2">
<b>Bold</b>, <i>italic</i>, <u>underline</u>.
</string>
String tagged_string = getString(R.string.tagged_string2);
tv.setText(tagged_string);
String tagged_string = getString(R.string.tagged_string2);
tv.setText(tagged_string);
运行结果:
HTML标签没有起作用,只是把HTML标签当成了字符串的内容取出来。
2、调用Html.fromHtml()方法转化一下:
String tagged_string = getString(R.string.tagged_string2);
tv.setText(Html.fromHtml(tagged_string));
String tagged_string = getString(R.string.tagged_string2);
tv.setText(Html.fromHtml(tagged_string));
执行结果:
HTML标签起作用。
3、调用一下我们前面提到的getText()方法:
tv.setText(getText(R.string.tagged_string2)); tv.setText(getText(R.string.tagged_string2));
HTML标签没有起作用,只是把HTML标签当成了字符串的内容取出来。
4、在其他的资源中通过ID引用:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tagged_string2" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tagged_string2"
/>
运行效果:
第二种HTML标签定义方式总结:
通过getString()方法获取字符串无HTML效果;
通过getString()方法获取字符串,然后调用Html.fromHtml()转化一下,有HTML效果;
通过getText()方法获取字符串无HTML效果;
在其他资源定义时通过ID引用该字符串无HTML效果。
第三种HTML标签定义方式,通过"CDATA"区段,使XML解析器忽略其中的节点标签:
<string name="tagged_string3">
<![CDATA[
<b>Bold</b>, <i>italic</i>, <u>underline</u>.
<br/>
<h1>font</h1>
]]>
</string>
<string name="tagged_string3">
<![CDATA[
<b>Bold</b>, <i>italic</i>, <u>underline</u>.
<br/>
<h1>font</h1>
]]>
</string>
1、我们通过getString()方法取得字符串然后设置为TextView的内容:
String tagged_string = getString(R.string.tagged_string3);
tv.setText(tagged_string);
String tagged_string = getString(R.string.tagged_string3);
tv.setText(tagged_string);
运行结果:
HTML标签没有起作用,只是把HTML标签当成了字符串的内容取出来。
2、调用Html.fromHtml()方法转化一下:
String tagged_string = getString(R.string.tagged_string3);
tv.setText(Html.fromHtml(tagged_string));
String tagged_string = getString(R.string.tagged_string3);
tv.setText(Html.fromHtml(tagged_string));
执行结果:
HTML标签起作用。
3、调用一下我们前面提到的getText()方法:
tv.setText(getText(R.string.tagged_string3));
tv.setText(getText(R.string.tagged_string3));
执行结果:
HTML标签没有起作用,只是把HTML标签当成了字符串的内容取出来。
4、在其他的资源中通过ID引用:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tagged_string3" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tagged_string3"
/>
看一下运行效果:
总结:第三种HTML标签定义方式,只是在定义时和第二种有所区别,一个是通过转义"<"字符,一个通过CDATA区段,调用方式相同。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="welcome">Welcome to <b>Android</b>!</string>
</resources>
不同的控件显示可能支持更多的HTML标签,例如TextView支持<br>、<h1>等更多的HTML标签。
4. 用HTML标记以及格式化字符串:
如果创建一个添加了样式的文本,同时还要使用格式化字符串。通常这样做是不会工作的,因为String.format()方法会去掉字符串中的所有样式信息。因此要围绕HTML标签进行字符转义工作,然后再格式化处理之后,调用fromHtml(String)方法来获取字符串资源,xml文件中增加:
<string name="format_tagged_string">Hello, %1$s! You have <b>%2$d new messages</b>.</string>
<string name="format_tagged_string">Hello, %1$s! You have <b>%2$d new messages</b>.</string>
上面用了"<"转义"<"字符,或者用CDATA区段,效果一样:
<string name="format_tagged_string">
<![CDATA[
Hello, %1$s! You have <b>%2$d new messages</b>.
]]>
</string> <string name="format_tagged_string">
<![CDATA[
Hello, %1$s! You have <b>%2$d new messages</b>.
]]>
</string>
java代码:
String tagged_string = getString(R.string.format_tagged_string);
tv.setText(String.format(tagged_string, "superman", 25));
String tagged_string = getString(R.string.format_tagged_string);
tv.setText(String.format(tagged_string, "superman", 25));
运行结果:
String.format()方法过滤掉了字符串中的样式信息。所以在调用format()方法后,还得调用一下 fromHtml(String)方法把HTML文本转换成样式文本,java代码改为:
String tagged_string = getString(R.string.format_tagged_string);
String formatStr = String.format(tagged_string, "superman", 25);
tv.setText(Html.fromHtml(formatStr));
String tagged_string = getString(R.string.format_tagged_string);
String formatStr = String.format(tagged_string, "superman", 25);
tv.setText(Html.fromHtml(formatStr));
运行结果:
HTML标签起了作用。
因为fromHtml(String)方法会格式化所有的HTML标签,所以对于包含HTML标记的特殊文本,必须调用htmlEncode(String)方法,确保其中的任何HTML字符都被转义。例如,如果传递给String.format()的字符串参数中包含了诸如”<”或”&”等符号,那么它们在被格式化之前,必须被转义,以便在格式化之后的字符被传递给fromHtml(String)方法时,被转换成初始编写的样子。
java代码改一下,传递的参数值有"<"特殊字符:
String tagged_string = getString(R.string.format_tagged_string);
String formatStr = String.format(tagged_string, "superman <", 25);
tv.setText(Html.fromHtml(formatStr));
String tagged_string = getString(R.string.format_tagged_string);
String formatStr = String.format(tagged_string, "superman <", 25);
tv.setText(Html.fromHtml(formatStr));
执行结果:
可以看出由于特殊字符的原因,丢掉了一些内容。
调用一下htmlEncode(string)方法,java代码改为:
String escapedUsername = TextUtils.htmlEncode("superman <");
String tagged_string = getString(R.string.format_tagged_string);
String formatStr = String.format(tagged_string, escapedUsername, 25) ;
tv.setText(Html.fromHtml(formatStr));
String escapedUsername = TextUtils.htmlEncode("superman <");
String tagged_string = getString(R.string.format_tagged_string);
String formatStr = String.format(tagged_string, escapedUsername, 25);
tv.setText(Html.fromHtml(formatStr));
执行结果:
结果正确,特殊字符被转义了。
四、 Android字符串高亮
|
五、 String
1.
2.
StringBuffer sbf = new StringBuffer();
String simple_string = getString(R.string.simple_string);
sbf.append("getString(simple_string):" + simple_string + "\n");
String single_quoted_string = getString(R.string.single_quoted_string);
sbf.append("getString(single_quoted_string):" + single_quoted_string + "\n");
String single_quoted_string2 = getString(R.string.single_quoted_string2);
sbf.append("getString(single_quoted_string2):" + single_quoted_string2 + "\n");
String double_quoted_string = getString(R.string.double_quoted_string);
sbf.append("getString(double_quoted_string):" + double_quoted_string + "\n");
String double_quoted_string2 = getString(R.string.double_quoted_string2);
sbf.append("getString(double_quoted_string):" + double_quoted_string2 + "\n");
tv.setText(sbf.toString());
import android.os.Bundle;
import android.app.Activity;
import android.widget.TextView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv1 = (TextView) findViewById(R.id.example1);
TextView tv2 = (TextView) findViewById(R.id.example2);
tv1.setText(getResources().getString(R.string.example1, 1000));
tv2.setText(getResources().getString(R.string.example2, 600, 300, 100));
}
}