Android字符串資源

有三種類型的字符串資源:

String:XML資源文件定義一個單獨的字符串。
String ArrayXML資源文件定義一個字符串數組。
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
語法:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="string_name">text_string</string>
</resources>
<resources>節點必須有,而且必須是根節點,沒有屬性。
<string>節點的值可以包括樣式化標記,注意如果字符串值包括單引號或雙引號字符,必須轉義。
XML文件中的單引號或雙引號:
        可以用“\”轉義符轉義單引號或雙引號;
        如果內容中有單引號,用雙引號括起來,不用轉義符也可以,例如:<string name="single_quoted_string">"single quoted'string"</string>;
如果內容中有單引號,如果不轉義符轉義或者雙引號括起來的話,編譯會報錯;
        如果內容中有雙引號,不能用單引號括起來(編譯會報錯),如果不用轉義符,取值時雙引號會被忽略。

做個實際例子測試一下:
      res/values/strings.xml文件中添加:
<!-- 測試字符串資源 -->
<string name="simple_string">simple string</string>
	
<string name="single_quoted_string">"single quoted'string"</string>
<!-- <string name="str">single quoted'string</string> 該行編譯時會報錯:error: Apostrophe not preceded by \ (in single quoted'string)	-->
<string name="single_quoted_string2">single quoted\'string</string>
	
<string name="double_quoted_string">\"double quotes\"</string>
<string name="double_quoted_string2">"double quotes"</string>
<!-- 	<string name="str3">'"double quotes"'</string> 該行編譯會報錯-->
     定義幾個Button按鈕,一個TextView控件用來顯示結果,java主要代碼:
		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());
執行結果:



String Array

文件存放路徑:res/values/filename.xml。文件名可以任意命名。
在Java文件中引用:R.array.string_array_name。
Resources res = getResources();
String[] stringArray = res.getStringArray(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>
<item>節點:可以包含樣式化格式的字符串。它的值可以是另外一個字符串資源,注意如果字符串值包括單引號或雙引號字符,必須轉義。
XML文件中的單引號或雙引號處理,參考上一部分的解釋。
還是做個實際例子測試一下:
      res/values/strings.xml文件中添加:
     
	 <!-- To support arrays -->
	<string-array name="test_array">
		<item>one</item>
		<item>two</item>
		<item>three</item>
		<item>@string/simple_string</item>	<!-- 引用其他stirng資源,上面定義過的string -->
		<item>"single quoted'string"</item>
		<item>single quoted\'string</item>
		<item>\"double quotes\"</item>
		<item>"double quotes"</item>
	</string-array>
java主要代碼:
	StringBuffer sbf = new StringBuffer();
	Resources res = getResources();
	String[] stringArray = res.getStringArray(R.array.test_array);
	for (String str : stringArray) {
		sbf.append(str);
		sbf.append("\n");
	}
	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
語法:
<?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 屬性:它是一個關鍵詞,用於指示該字符串所使用的時機。有效值與簡單的例子如下:

說明
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文件中添加:

<string name="format_string">
	Hello, I am %2$d years old, My name is %1$s.
</string>
java主要代碼:

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標籤定義方式:

<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);
運行結果:


HTML標籤沒有起作用。

2、調用Html.fromHtml()方法轉化一下:

String tagged_string = getString(R.string.tagged_string1);
tv.setText(Html.fromHtml(tagged_string));
執行結果:

HTML標籤任然沒有起作用。

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

tv.setText(getText(R.string.tagged_string1));

HTML標籤起了作用。

4、在其他的資源中通過ID引用:
我們定義一個Button,Button的Text設置爲我們上面定義的String(ID爲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標籤定義方式,通過"&lt;"轉義"<"符號

<string name="tagged_string2">
       &lt;b>Bold&lt;/b>, &lt;i>italic&lt;/i>, &lt;u>underline&lt;/u>.
</string>

下面我們測試一下第二種方式如何使用:

1、我們通過getString()方法取得字符串然後設置爲TextView的內容:

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));
執行結果:

HTML標籤起作用。

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

tv.setText(getText(R.string.tagged_string2));

HTML標籤沒有起作用,只是把HTML標籤當成了字符串的內容取出來。

4、在其他的資源中通過ID引用:
我們定義一個Button,Button的Text設置爲我們上面定義的String(ID爲tagged_string1):

<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>

下面我們測試一下第三種方式如何使用:

1、我們通過getString()方法取得字符串然後設置爲TextView的內容:

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));

執行結果:


HTML標籤起作用。

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

tv.setText(getText(R.string.tagged_string3));

執行結果:


HTML標籤沒有起作用,只是把HTML標籤當成了字符串的內容取出來。

4、在其他的資源中通過ID引用:
我們定義一個Button,Button的Text設置爲我們上面定義的String(ID爲tagged_string1):

<Button 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/tagged_string3"
 />

看一下運行效果:


總結:第三種HTML標籤定義方式,只是在定義時和第二種有所區別,一個是通過轉義"<"字符,一個通過CDATA區段,調用方式相同。


用HTML標記以及格式化字符串

如果創建一個添加了樣式的文本,同時還要使用格式化字符串。通常這樣做是不會工作的,因爲String.format()方法會去掉字符串中的所有樣式信息。因此要圍繞HTML標籤進行字符轉義工作,然後再格式化處理之後,調用fromHtml(String)方法來獲取字符串資源,
還是用例子測試,xml文件中增加:
<string name="format_tagged_string">Hello, %1$s! You have &lt;b>%2$d new messages&lt;/b>.</string>
上面用了"&lt;"轉義"<"字符,或者用CDATA區段,效果一樣:
<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.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));
運行結果:

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));
執行結果:
可以看出由於特殊字符的原因,丟掉了一些內容。

調用一下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));
執行結果:

結果正確,特殊字符被轉義了。


最後附上測試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


發佈了10 篇原創文章 · 獲贊 5 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章