字串資源

字串資源提供應用程式所使用的文字字串,並可選擇文字樣式和格式。有三種類型的資源可為應用程式提供字串:

字串
提供單一字串的 XML 資源。
字串陣列
提供字串陣列的 XML 資源。
數量字串 (複數)
XML 資源,包含複數形式使用的不同字串。

所有字串都可以套用樣式標記和格式化引數。如需樣式和格式化字串的相關資訊,請參閱「格式化和樣式」。

字串

可從應用程式或從其他資源檔案參照的單一字串 (例如:XML 版面配置)。

注意:字串是一種使用 name 屬性所提供值 (而非 XML 檔案的名稱) 參照的簡單資源。因此,您可以在一個 XML 檔案中,於一個 <resources> 元素下合併字串資源與其他簡單資源。

檔案位置:
res/values/filename.xml
您可以使用任意檔案名稱。<string> 元素的 name 會做資源 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。
例如:
XML 檔案儲存在 res/values/strings.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" />

此應用程式程式碼會擷取字串:

Kotlin

val string: String = getString(R.string.hello)

Java

String string = getString(R.string.hello);

您可以使用 getString(int)getText(int) 擷取字串。getText(int) 會保留任何套用至字串的 RTF 格式樣式。

字串陣列

可從應用程式參照的字串陣列。

注意:字串陣列是一種使用 name 屬性提供的值 (而非 XML 檔案的名稱) 參照的簡單資源。因此,您可以在一個 XML 檔案中,於一個 <resources> 元素下合併字串陣列資源與其他簡單資源。

檔案位置:
res/values/filename.xml
您可以使用任意檔案名稱。<string-array> 元素的 name 會做資源 ID 使用。
編譯資源資料類型:
String 陣列的資源指標。
資源參照:
Java:R.array.string_array_name
XML:@[package:]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> 元素的子項。請注意,您必須逸出格號和引號。請參閱下方的「格式化和樣式」,以瞭解如何正確設定字串的樣式及格式。

沒有任何屬性。

例如:
XML 檔案儲存在 res/values/strings.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>

此應用程式程式碼會擷取字串陣列:

Kotlin

val array: Array<String> = resources.getStringArray(R.array.planets_array)

Java

Resources res = getResources();
String[] planets = res.getStringArray(R.array.planets_array);

數量字串 (複數)

不同的語言,對於數量的文法一致性有不同的規則。以英文為例,數量 1 是一種特殊情況。我們會寫「1 Book」,但如果是其他數量,則會寫「n Books」。單數與複數的區別非常重要,但其他語言則需採用更精細的方式。Android 支援的完整組合為 zeroonetwofewmanyother

決定特定語言和數量的使用方式規則可能會很複雜,因此 Android 提供 getQuantityString() 等方式,協助您選擇合適的資源。

雖然過去稱為「數量字串」(在 API 中依然如此稱呼),但數量字串「只能」用於複數形式。舉例來說,您不應該使用數量字串實作如 Gmail 的「Inbox」(收件匣) 與有未讀郵件時顯示的「Inbox (12)」這類的項目。使用數量字串而不是 if 聲明,也許看起來很方便,但一定要注意的一點是某些語言 (例如中文) 就完全沒有單複數的文法差別,因此一律會取得 other 字串。

選擇要使用的字串時,這完全是根據文法的「必要性」而決定。對英文來說,即使數量為 0,也會忽略 zero 的字串,這是因為 0 與 2,或是任何其他除了 1 以外的數字並沒有文法上的差異 (「Zero Books」、「One Book」、「Two Books」等等)。反之,在韓文中,「只會」用到 other 字串。

不過,別誤以為 two 只能套用至數量為 2 的情況:在某種語言中,有可能必須將 2、12、102 等數量視為同一種情況,並採取與其他數量不同的處理方式。如要瞭解語言規則的差異,請諮詢翻譯人員。

如果訊息中不含數量,就可能不適合使用複數。以立陶宛語為例,1 和 101 都使用單數形式,因此「1 本書」會翻譯為「1 knyga」,「101 本書」會翻譯為「101 knyga」。而「一本書」是「knyga」,「許多本書」則是「daug knygų」。如果英文複數訊息包含「一本書」(單數) 和「許多本書」(複數),但卻沒有實際數字,則可以翻譯為「knyga」(一本書)/「daug knygų」(許多本書),不過根據立陶宛語的規則,系統會在數字為 101 時,顯示「knyga」(一本書)。

通常來說,使用「Books: 1」等數量中立的寫法,就可以避免使用數量字串。如果應用程式可以接受使用這種樣式,您和您的翻譯人員都會輕鬆很多。

在 API 24 以上版本中,您可以改用功能更強大的 ICU MessageFormat 類別。

注意:複數集合是一種使用 name 屬性提供的值 (而非 XML 檔案的名稱) 參照的簡單資源。因此,您可以在一個 XML 檔案中,於一個 <resources> 元素下合併複數資源與其他簡單資源。

檔案位置:
res/values/filename.xml
您可以使用任意檔案名稱。<plurals> 元素的 name 會做資源 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
「關鍵字」。表示此字串使用時機的值。有效的值,僅在括號中列舉部分範例:
說明
zero當語言需要以特別方式處理數字 0 時 (如阿拉伯文)。
one當語言需要以特別的方式處理「一」等數字時 (如英文中的數字 1 以及大多數其他語言的數字 1;如果是俄文,任何以 1 結尾、結尾為 11 的號碼都屬於此類別)。
two當語言需要以特別的方式處理「二」等數字時 (如威爾斯語的 2,或斯洛維尼亞語的 102)。
few當語言需要以特別的方式處理「小」數字時 (如捷克文的 2、3 和 4;或波蘭文中以 2、3 或 4 結尾,但並非 12、13 或 14 的數字)。
many當語言需要以特別的方式處理「大」數字時 (如馬爾他文結尾為 11-99 的數字)。
other當語言不需以特別的方式處理任何數量時 (如中文的所有數字,或英文中的 42)。
例如:
XML 檔案儲存在 res/values/strings.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>

XML 檔案儲存在 res/values-pl/strings.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>

使用方式:

Kotlin

val count = getNumberOfSongsAvailable()
val songsFound = resources.getQuantityString(R.plurals.numberOfSongsAvailable, count, count)

Java

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

使用 getQuantityString() 方法時,如果您的字串包含有數字的字串格式,您就必須傳遞 count 兩次。舉例來說,如果是 %d songs found 字串,第一個 count 參數會選取適當的複數字串,並在 %d 預留位置插入第二個 count 參數。如果複數字串不包含字串格式,則不需要傳遞第三個參數至 getQuantityString

格式與樣式

以下是有關正確設定字串資源格式和樣是的幾點重要注意事項。

處理特殊字元

如果字串包含 XML 中有特殊用途的字元,您就必須根據標準 XML/HTML 逸出規則逸出字元。如果需要逸出 Android 中具有特殊意義的字元,則應於前面加上反斜線。

根據預設,Android 會將空白字元的序列收合在單一空格中。使用雙引號括住字串的相關部分,就可以避免出現此情況。在這種情況下,所有空白字元 (包括換行符號) 都會保留在引號內的區域中。雙引號也可讓您使用一般的單一未逸出引號。

字元 逸出形式
@ \@
? \?
換行 \n
Tab 鍵 \t
U+XXXX 萬國碼 (Unicode) 字元 \uXXXX
單引號 (')

下列任何項目:

  • \'
  • 以雙引號括住整個字串 (例如:"This'll work")
雙引號 (") \"

請注意,使用單引號括住字串並沒有效果。

以 XML 剖析資源檔案後,就會收合空白字元,且 Android 會逸出。也就是說,<string> &#32; &#8200; &#8195;</string> (空格、標點符號空格、萬國碼 (Unicode) Em 空格) 全部會收合成單一空格 (" "),這是因為以 XML 剖析檔案之後,這些項目都會是萬國碼 (Unicode) 空格。如要保留這些空格,您可以加上引號 (<string>" &#32; &#8200; &#8195;"</string>) 或使用 Android 逸出功能 (<string> \u0032 \u8200 \u8195</string>)。

注意:從 XML 剖析器的角度來看,<string>"Test this"</string><string>&quot;Test this&quot;</string> 之間沒有任何差異。這兩種形式都不會顯示任何引號,但會觸發 Android 空格保留引述 (在這種情況下不會有實際效果)。

格式化字串

如果您需要格式化字串,則可以在字串資源中加入格式引數,如下方範例資源所示。

<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>

在這個範例中,格式字串有兩個引數:%1$s 是字串,而 %2$d 是十進位數字。然後呼叫 getString(int, Object...) 以格式化字串。例如:

Kotlin

var text = getString(R.string.welcome_messages, username, mailCount)

Java

String text = 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>、<cite>、<dfn>、<em>
  • 文字加大 25%:<big>
  • 文字縮小 20%:<small>
  • 設定字型屬性:<font face=”font_family“ color=”hex_color”>。可能的字型系列範例包括 monospaceserifsans_serif
  • 設定等寬字型系列:<tt>
  • 刪除線:<s>、<strike>、<del>
  • 底線:<u>
  • 上標:<sup>
  • 下標:<sub>
  • 項目符號:<ul>、<li>
  • 分行符號:<br>
  • 除號:<div>
  • CSS 樣式:<span style=”color|background_color|text-decoration”>
  • 段落:<p dir=”rtl | ltr” style=”…”>

如未套用格式,您可以呼叫 setText(java.lang.CharSequence) 以直接設定 TextView 文字。但是,在某些情況下,您也許會想建立也會做格式字串使用的樣式文字資源。一般而言,這並不會發揮作用,因為 format(String, Object...)getString(int, Object...) 方法會去除字串中的所有樣式資訊。解決方法是編寫有逸出實體的 HTML 標記,然後在格式化後使用 fromHtml(String) 進行復原。例如:

  1. 將具有樣式的文字資源儲存為 HTML 逸出字串:
    <resources>
      <string name="welcome_messages">Hello, %1$s! You have &lt;b>%2$d new messages&lt;/b>.</string>
    </resources>
    

    在此格式字串中,系統會加入 <b> 元素。請注意,左括號是使用 &lt; 標記法的 HTML 逸出。

  2. 然後依照一般方式格式化字串,不過也要呼叫 fromHtml(String),將 HTML 文字轉換為樣式文字:

    Kotlin

    val text: String = getString(R.string.welcome_messages, username, mailCount)
    val styledText: Spanned = Html.fromHtml(text, FROM_HTML_MODE_LEGACY)
    

    Java

    String text = getString(R.string.welcome_messages, username, mailCount);
    Spanned styledText = Html.fromHtml(text, FROM_HTML_MODE_LEGACY);
    

由於 fromHtml(String) 方法會格式化所有 HTML 實體,因此請務必在搭配格式化文字的字串中使用 htmlEncode(String) 逸出任何可能的 HTML 字元。舉例來說,如果要格式化的字串包含「<」或「&」等字元,必須在格式化前逸出這些字元,才能在透過 fromHtml(String) 傳遞格式化字串時,以原始的編寫方式顯示字元。例如:

Kotlin

val escapedUsername: String = TextUtils.htmlEncode(username)

val text: String = getString(R.string.welcome_messages, escapedUsername, mailCount)
val styledText: Spanned = Html.fromHtml(text, FROM_HTML_MODE_LEGACY)

Java

String escapedUsername = TextUtils.htmlEncode(username);

String text = getString(R.string.welcome_messages, escapedUsername, mailCount);
Spanned styledText = Html.fromHtml(text);

使用 Spannables 設定樣式

Spannable 是一個文字物件,您可以使用顏色和字體粗細等字體屬性設定樣式。您可以使用 SpannableStringBuilder 建構文字,然後將 android.text.style 套件中定義的樣式套用至文字。

您可以使用下列輔助方法完成大部分 Spannable 文字建立。

Kotlin

/**
 * 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 fun apply(content: Array<out CharSequence>, vararg tags: Any): CharSequence {
    return SpannableStringBuilder().apply {
        openTags(tags)
        content.forEach { charSequence ->
            append(charSequence)
        }
        closeTags(tags)
    }
}

/**
 * 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 fun Spannable.openTags(tags: Array<out Any>) {
    tags.forEach { tag ->
        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 fun Spannable.closeTags(tags: Array<out Any>) {
    tags.forEach { tag ->
    if (length > 0) {
            setSpan(tag, 0, length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
        } else {
            removeSpan(tag)
        }
    }
}

Java

/**
 * 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 applyStyles(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);
        }
    }
}

下列 bolditaliccolor 方法會納入上述輔助方法,並展示 android.text.style 套件中定義的特定樣式範例。您可以建立類似的方法完成其他類型的文字樣式設定。

Kotlin

/**
 * Returns a CharSequence that applies boldface to the concatenation
 * of the specified CharSequence objects.
 */
fun bold(vararg content: CharSequence): CharSequence = apply(content, StyleSpan(Typeface.BOLD))

/**
 * Returns a CharSequence that applies italics to the concatenation
 * of the specified CharSequence objects.
 */
fun italic(vararg content: CharSequence): CharSequence = apply(content, StyleSpan(Typeface.ITALIC))

/**
 * Returns a CharSequence that applies a foreground color to the
 * concatenation of the specified CharSequence objects.
 */
fun color(color: Int, vararg content: CharSequence): CharSequence =
        apply(content, ForegroundColorSpan(color))

Java

/**
 * 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));
}

以下範例說明如何鏈結這些方法,為詞組中的個別字詞套用不同的樣式:

Kotlin

// Create an italic "hello, " a red "world",
// and bold the entire sequence.
val text: CharSequence = bold(italic(getString(R.string.hello)),
        color(Color.RED, getString(R.string.world)))

Java

// Create an italic "hello, " a red "world",
// and bold the entire sequence.
CharSequence text = bold(italic(getString(R.string.hello)),
    color(Color.RED, getString(R.string.world)));

core-ktx Kotlin 模組也包含擴充功能函式,可讓您更輕鬆地使用 Span。詳情請參閱 GitHub 的 android.text 套件文件。

如要進一步瞭解如何使用 Span,請參閱下列連結:

使用註解設定樣式

使用 Annotation 類別與 strings.xml 資源檔案中的 <annotation> 標記,即可套用複雜或自訂樣式。註解標記可讓您透過在 XML 中定義鍵/值組合的方式,標記自訂樣式的字串部分,然後架構就可以轉換成 Annotation Span。然後您就可以擷取這些註解,並使用鍵和值套用樣式。

建立註解時,請務必在每個 string.xml 檔案的所有翻譯中加入 <annotation> 標記。


在所有語言的「Text」字詞套用自訂字體

範例 - 新增自訂字體

  1. 新增 <annotation> 標記並定義鍵/值組合。在此情況下,鍵為「字型」,值則是要使用的字型類型:「title_emphasis」

    // values/strings.xml
    <string name="title">Best practices for <annotation font="title_emphasis">text</annotation> on Android</string>
    
    // values-es/strings.xml
    <string name="title"><annotation font="title_emphasis">Texto</annotation> en Android: mejores prácticas</string>
    
  2. 載入字串資源,然後使用「字型」鍵尋找註解。接著建立自訂 Span 並取代現有的 Span。

    Kotlin

    // get the text as SpannedString so we can get the spans attached to the text
    val titleText = getText(R.string.title) as SpannedString
    
    // get all the annotation spans from the text
    val annotations = titleText.getSpans(0, titleText.length, Annotation::class.java)
    
    // create a copy of the title text as a SpannableString.
    // the constructor copies both the text and the spans. so we can add and remove spans
    val spannableString = SpannableString(titleText)
    
    // iterate through all the annotation spans
    for (annotation in annotations) {
       // look for the span with the key font
       if (annotation.key == "font") {
          val fontName = annotation.value
          // check the value associated to the annotation key
          if (fontName == "title_emphasis") {
             // create the typeface
             val typeface = getFontCompat(R.font.permanent_marker)
             // set the span at the same indices as the annotation
             spannableString.setSpan(CustomTypefaceSpan(typeface),
                titleText.getSpanStart(annotation),
                titleText.getSpanEnd(annotation),
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
          }
       }
    }
    
    // now, the spannableString contains both the annotation spans and the CustomTypefaceSpan
    styledText.text = spannableString
    

    Java

    // get the text as SpannedString so we can get the spans attached to the text
    SpannedString titleText = (SpannedString) getText(R.string.title);
    
    // get all the annotation spans from the text
    Annotation[] annotations = titleText.getSpans(0, titleText.length(), Annotation.class);
    
    // create a copy of the title text as a SpannableString.
    // the constructor copies both the text and the spans. so we can add and remove spans
    SpannableString spannableString = new SpannableString(titleText);
    
    // iterate through all the annotation spans
    for (Annotation annotation: annotations) {
      // look for the span with the key font
      if (annotation.getKey().equals("font")) {
        String fontName = annotation.getValue();
        // check the value associated to the annotation key
        if (fontName.equals("title_emphasis")) {
        // create the typeface
        Typeface typeface = ResourcesCompat.getFont(this, R.font.roboto_mono);
        // set the span at the same indices as the annotation
        spannableString.setSpan(new CustomTypefaceSpan(typeface),
          titleText.getSpanStart(annotation),
          titleText.getSpanEnd(annotation),
          Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
      }
    }
    
    // now, the spannableString contains both the annotation spans and the CustomTypefaceSpan
    styledText.text = spannableString;
    

如果多次使用相同的文字,建議您建構 SpannableString 物件一次,然後視需要重複使用,以避免出現潛在的效能和記憶體問題。

如需更多註解使用範例,請參閱「在 Android 中設定國際化文字樣式

註解 Span 和文字 Parcel

由於 Annotation Span 也是 ParcelableSpans,因此鍵/值組合會進行 Parcel 處理和解除。只要 Parcel 的接收端知道如何解譯註解,您就可以使用 Annotation Span 套用自訂樣式至以 Parcel 處理的文字。

如要在傳遞文字至意圖軟體包時保留自訂樣式,首先您必須在文字中加入 Annotation Span。您可以透過 <annotation> 標記在 XML 資源中完成此操作 (如上例所示),或者是利用建立新的 Annotation,然後將其設定為 Span (如下所示) 以完成此操作:

Kotlin

val spannableString = SpannableString("My spantastic text")
val annotation = Annotation("font", "title_emphasis")
spannableString.setSpan(annotation, 3, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)

// start Activity with text with spans
val intent = Intent(this, MainActivity::class.java)
intent.putExtra(TEXT_EXTRA, spannableString)
startActivity(intent)

Java

SpannableString spannableString = new SpannableString("My spantastic text");
Annotation annotation = new Annotation("font", "title_emphasis");
spannableString.setSpan(annotation, 3, 7, 33);

// start Activity with text with spans
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra(TEXT_EXTRA, spannableString);
this.startActivity(intent);

Bundle 擷取文字做為 SpannableString,然後剖析附加的註解,如上例所示。

Kotlin

// read text with Spans
val intentCharSequence = intent.getCharSequenceExtra(TEXT_EXTRA) as SpannableString

Java

// read text with Spans
SpannableString intentCharSequence = (SpannableString)intent.getCharSequenceExtra(TEXT_EXTRA);

如要進一步瞭解文字樣式,請參閱下列連結: