字符串资源
字符串资源为应用程序提供可选的文本样式和格式的文本字符串。有三种类型的资源可以为您的应用程序提供字符串:
String
提供单个字符串的XML资源。
String Array
提供字符串数组的XML资源。
Quantity Strings (Plurals)
XML资源,带有不同的字符串以进行复数化
所有字符串都能够应用一些样式标记和格式化参数。有关样式和格式化字符串的信息,请参阅有关格式和样式的部分。
String
可以从应用程序或其他资源文件(例如XML布局)引用的单个字符串。
注意:字符串是使用name属性中提供的值(而不是XML文件的名称)引用的简单资源。因此,您可以将字符串资源与一个XML文件中的其他简单资源组合在一个<resources>元素下。
文件位置:
res/values/filename.xml
文件名是任意的。 <string>元素的名称将用作资源ID。
编译资源数据类型:
指向String的资源指针。
资源参考:
在Java中:R.string.string_name
在XML中:@ string / string_name
语法:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string
name="string_name"
>text_string</string>
</resources>
元素:
<resources>
必要。这必须是根节点。
没有属性。
<string>
一个字符串,可以包含样式标记。请注意,您必须转义撇号和引号。有关如何正确设置字符串样式和格式的详细信息,请参阅下面的格式和样式。
属性:
name
字符串。字符串的名称。此名称将用作资源ID。
例子:
保存在res / values / strings.xml的XML文件:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello!</string>
</resources>
此布局XML将字符串应用于视图:
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
此应用程序代码检索字符串:
String string = getString(R.string.hello);
您可以使用getString(int)或getText(int)来检索字符串。 getText(int)将保留应用于字符串的任何富文本样式。
String Array
可以从应用程序引用的字符串数组。
注意:字符串数组是使用name属性中提供的值(而不是XML文件的名称)引用的简单资源。因此,您可以将字符串数组资源与一个XML文件中的其他简单资源组合在一个<resources>元素下。
文件位置:
res/values/filename.xml
文件名是任意的。 <string-array>元素的名称将用作资源ID。
编译资源数据类型:
指向字符串数组的资源指针。
资源参考:
在Java中:R.array.string_array_name
语法:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array
name="string_array_name">
<item
>text_string</item>
</string-array>
</resources>
元素
<resources>
必要。这必须是根节点。
没有属性。
<string-array>
定义一个字符串数组。包含一个或多个<item>元素。
属性:
name
字符串。数组的名称。此名称将用作引用该数组的资源ID。
<item>
一个字符串,可以包含样式标记。该值可以是对另一个字符串资源的引用。必须是<string-array>元素的子元素。请注意,您必须转义撇号和引号。有关正确设置字符串样式和格式的信息,请参阅下面的格式和样式。
没有属性。
例子:
保存在res / values / strings.xml的XML文件:
<?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>
此应用程序代码检索字符串数组:
Resources res = getResources();
String[] planets = res.getStringArray(R.array.planets_array);
Quantity Strings (Plurals)
不同语言对语法协议与数量有不同的规则。例如,在英语中,数量1是一种特殊情况。我们写“1本书”,但对于任何其他数量,我们写“n本书”。单数和复数之间的区别非常普遍,但其他语言可以做出更精细的区分。 Android支持的全套设置为零,一,二,少数,多数等。
决定使用哪种情况用于给定语言和数量的规则可能非常复杂,因此Android为您提供了诸如getQuantityString()之类的方法来为您选择适当的资源。
虽然历史上称为“数量字符串”(在API中仍然称为数量字符串),但数量字符串应仅用于复数。例如,当有未读消息时,使用数量字符串来实现诸如Gmail的“收件箱”与“收件箱(12)”之类的内容将是错误的。使用数量字符串而不是if语句似乎很方便,但重要的是要注意某些语言(例如中文)根本不会产生这些语法上的区别,所以你总是得到另一个字符串。
选择使用哪个字符串完全基于语法必要性。在英语中,即使数量为0,也会忽略零字符串,因为0在语法上与2不相同,或者除了1以外的任何其他数字(“零书”,“一本书”,“两本书”和等等)。相反,在韩语中只会使用其他字符串。
不要因为两个声音只能应用于数量2而被误导:一种语言可能要求2,12,102(等等)都被视为彼此相似但与其他不同数量。依靠你的翻译来了解他们的语言实际上坚持的区别。
通常可以通过使用数量中性的配方来避免数量字符串,例如“Books:1”。如果这种风格与您的应用程序保持一致,这将使您的生活和翻译人员的生活更轻松。
注意:复数集合是使用name属性中提供的值(而不是XML文件的名称)引用的简单资源。因此,您可以将多个资源与一个XML文件中的其他简单资源组合在一个<resources>元素下。
文件位置:
res/values/filename.xml
文件名是任意的。 <plurals>元素的名称将用作资源ID。
资源参考:
在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>
元素:
<resources>
需要。这必须是根节点。
没有属性。
<plurals>
字符串的集合,其中,根据事物的数量提供一个字符串。包含一个或多个<item>元素。
属性:
name
字符串。这对字符串的名称。此名称将用作资源ID。
<item>
复数或单数字符串。该值可以是对另一个字符串资源的引用。必须是<plurals>元素的子元素。请注意,您必须转义撇号和引号。有关正确设置字符串样式和格式的信息,请参阅下面的格式和样式。
属性:
quantity
关键词。一个值,指示何时应使用此字符串。有效值,括号中有非详尽的示例:
Value | Description |
zero | 当语言需要对数字0进行特殊处理时(如阿拉伯语)。 |
one | 当语言需要对一个数字进行特殊处理时(如英语和大多数其他语言中的数字1;在俄语中,任何以1结尾但不以11结尾的数字都在此类中)。 |
two | 当语言需要对两个数字进行特殊处理时(如威尔士语中的2或斯洛文尼亚语中的102)。 |
few | 当语言需要特殊处理“小”数字时(如捷克语中的2,3和4;或者以波兰语结尾2,3或4但不是12,13或14的数字)。 |
many | 当语言需要特殊处理“大号”时(如马耳他语中以11-99结尾的数字)。 |
other | 当语言不需要特定处理给定数量时(如中文所有数字,或英语42)。 |
例子:
保存在res / values / strings.xml的XML文件:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<plurals name="numberOfSongsAvailable">
<!--
As a developer, you should always supply "one" and "other"
strings. Your translators will know which strings are actually
needed for their language. Always include %d in "one" because
translators will need to use %d for languages where "one"
doesn't mean 1 (as explained above).
-->
<item quantity="one">%d song found.</item>
<item quantity="other">%d songs found.</item>
</plurals>
</resources>
保存在res / values-pl / strings.xml的XML文件:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<plurals name="numberOfSongsAvailable">
<item quantity="one">Znaleziono %d piosenkę.</item>
<item quantity="few">Znaleziono %d piosenki.</item>
<item quantity="other">Znaleziono %d piosenek.</item>
</plurals>
</resources>
Java代码:
int count = getNumberOfsongsAvailable();
Resources res = getResources();
String songsFound = res.getQuantityString(R.plurals.numberOfSongsAvailable, count, count);
使用getQuantityString()方法时,如果字符串包含带数字的字符串格式,则需要将计数传递两次。例如,对于找到的字符串%d首歌曲,第一个计数参数选择适当的复数字符串,第二个计数参数插入%d占位符。如果您的复数字符串不包含字符串格式,则不需要将第三个参数传递给getQuantityString。
Formatting and Styling
以下是您应该了解的有关如何正确格式化和设置字符串资源样式的一些重要事项。
转义撇号和引号
如果字符串中有撇号('),则必须使用反斜杠(\')将其转义或将字符串括在双引号(“”)中。例如,以下是一些有效且无效的字符串:
<string name="good_example">This\'ll work</string>
<string name="good_example_2">"This'll also work"</string>
<string name="bad_example">This doesn't work</string>
<!-- Causes a compile error -->
如果你的字符串中有双引号,则必须将其转义(\“)。用单引号括起字符串不起作用。
<string name="good_example">This is a \"good string\".</string>
<string name="bad_example">This is a "bad string".</string>
<!-- Quotes are stripped; displays as: This is a bad string. -->
<string name="bad_example_2">'This is another "bad string".'</string>
<!-- Causes a compile error -->
格式化字符串
如果需要使用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);
使用HTML标记进行样式设置
您可以使用HTML标记为字符串添加样式。例如:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="welcome">Welcome to <b>Android</b>!</string>
</resources>
支持的HTML元素包括:
- <b>表示粗体文字。
- <i>用于斜体文字。
- <u>用于下划线文字。
有时您可能希望创建一个样式化的文本资源,该资源也用作格式字符串。通常,这不起作用,因为String.format(String,Object ...)方法将从字符串中删除所有样式信息。解决这个问题的方法是使用转义实体编写HTML标记,然后在格式化之后使用fromHtml(String)恢复这些实体。例如:
1.将样式化文本资源存储为HTML转义字符串:
<resources>
<string name="welcome_messages">Hello, %1$s! You have <b>%2$d new messages</b>.</string>
</resources>
在此格式化字符串中,添加了<b>元素。请注意,使用&lt;开头括号进行HTML转义。符号。
2.然后像往常一样格式化字符串,但也调用fromHtml(String)将HTML文本转换为样式文本:
Resources res = getResources();
String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);
CharSequence styledText = Html.fromHtml(text);
因为fromHtml(String)方法将格式化所有HTML实体,所以请确保使用htmlEncode(String)转义与格式化文本一起使用的字符串中的任何可能的HTML字符。例如,如果您要将字符串参数传递给可能包含“<”或“&”等字符的String.format(),则必须在格式化之前对它们进行转义,以便在格式化的字符串通过fromHtml传递时(字符串),字符以最初编写的方式出现。例如:
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);
使用Spannables进行造型
Spannable是一个文本对象,您可以使用字体属性(如颜色和字体粗细)进行样式设置。您可以使用SpannableStringBuilder构建文本,然后将android.text.style包中定义的样式应用于文本。
您可以使用以下帮助程序方法来设置创建可跨越文本的大部分工作:
/**
* Returns a CharSequence that concatenates the specified array of CharSequence
* objects and then applies a list of zero or more tags to the entire range.
*
* @param content an array of character sequences to apply a style to
* @param tags the styled span objects to apply to the content
* such as android.text.style.StyleSpan
*
*/
private static CharSequence apply(CharSequence[] content, Object... tags) {
SpannableStringBuilder text = new SpannableStringBuilder();
openTags(text, tags);
for (CharSequence item : content) {
text.append(item);
}
closeTags(text, tags);
return text;
}
/**
* Iterates over an array of tags and applies them to the beginning of the specified
* Spannable object so that future text appended to the text will have the styling
* applied to it. Do not call this method directly.
*/
private static void openTags(Spannable text, Object[] tags) {
for (Object tag : tags) {
text.setSpan(tag, 0, 0, Spannable.SPAN_MARK_MARK);
}
}
/**
* "Closes" the specified tags on a Spannable by updating the spans to be
* endpoint-exclusive so that future text appended to the end will not take
* on the same styling. Do not call this method directly.
*/
private static void closeTags(Spannable text, Object[] tags) {
int len = text.length();
for (Object tag : tags) {
if (len > 0) {
text.setSpan(tag, 0, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else {
text.removeSpan(tag);
}
}
}
以下粗体,斜体和颜色方法向您展示如何调用辅助方法来应用android.text.style包中定义的样式。您可以创建类似的方法来执行其他类型的文本样式。
/**
* Returns a CharSequence that applies boldface to the concatenation
* of the specified CharSequence objects.
*/
public static CharSequence bold(CharSequence... content) {
return apply(content, new StyleSpan(Typeface.BOLD));
}
/**
* Returns a CharSequence that applies italics to the concatenation
* of the specified CharSequence objects.
*/
public static CharSequence italic(CharSequence... content) {
return apply(content, new StyleSpan(Typeface.ITALIC));
}
/**
* Returns a CharSequence that applies a foreground color to the
* concatenation of the specified CharSequence objects.
*/
public static CharSequence color(int color, CharSequence... content) {
return apply(content, new ForegroundColorSpan(color));
}
下面是一个如何链接这些方法以创建一个字符序列的示例,该字符序列具有应用于单个单词的不同类型的样式:
// Create an italic "hello, " a red "world",
// and bold the entire sequence.
CharSequence text = bold(italic(res.getString(R.string.hello)),
color(Color.RED, res.getString(R.string.world)));