Android官方文件—APP資源(Resource Types) (String)
字串資源
字串資源為應用程式提供可選的文字樣式和格式的文字字串。有三種類型的資源可以為您的應用程式提供字串:
提供單個字串的XML資源。
提供字串陣列的XML資源。
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)));