字符串资源

字符串资源可为您的应用提供文本字符串,支持可选的文本样式和格式。有三种类型的资源可以为您的应用提供字符串:

字符串
提供单个字符串的 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
String。字符串的名称。此名称用作资源 ID。
示例
XML 文件保存在 res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello!</string>
</resources>

此布局 XML 将字符串应用于 View

<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) 会保留应用于字符串的任何富文本样式。

字符串数组

一个可以从应用引用的字符串数组。

注意:字符串数组是一种简单资源,使用 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
String。数组的名称。此名称用作引用数组的资源 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 中有未读邮件时的“收件箱”与“收件箱 (12)”的功能,那是错误的。使用数量字符串代替 if 语句可能看起来很方便,但请务必注意,有些语言(例如中文)根本不进行这些语法区分,因此您将始终获得 other 字符串。

选择使用哪个字符串完全基于语法必要性。在英语中,即使数量为 0,zero 的字符串也会被忽略,因为 0 在语法上与 2 或除 1 之外的任何其他数字没有区别(“零本书”、“一本书”、“两本书”等等)。相反,在韩语中使用 other 字符串。

也不要被诸如 two 听起来似乎只适用于数量 2 这样的事实误导:一种语言可能要求 2、12、102(等等)都被视为同一类,但与其他数量不同。依靠您的翻译人员来了解他们的语言实际坚持的区分。

如果您的消息不包含数量数字,它可能不是复数的好选择。例如,在立陶宛语中,单数形式用于 1 和 101,因此“1 book”被翻译为“1 knyga”,而“101 books”被翻译为“101 knyga”。同时,“a book”是“knyga”,而“many books”是“daug knygų”。如果一个英语复数消息包含“a book”(单数)和“many books”(复数)而没有实际数字,它可以被翻译为“knyga”(一本书)/“daug knygų”(许多书),但根据立陶宛语规则,当数字恰好是 101 时,它将显示“knyga”(一本书)。

通常可以通过使用数量中性的表述(例如“书籍: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
String。该对字符串的名称。此名称用作资源 ID。
<item>
一个复数或单数字符串。该值可以是对另一个字符串资源的引用。必须是 <plurals> 元素的子元素。请注意,您必须转义撇号和引号。有关如何正确设置字符串样式和格式的信息,请参阅下方的格式和样式

属性

quantity
关键字。一个值,指示何时应使用此字符串。有效值(括号中为非穷尽示例)
说明
zero当语言要求对数字 0 进行特殊处理时(如在阿拉伯语中)。
one当语言要求对类似 1 的数字进行特殊处理时(如在英语和大多数其他语言中的数字 1;在俄语中,任何以 1 结尾但不以 11 结尾的数字都属于此类)。
two当语言要求对类似 2 的数字进行特殊处理时(如在威尔士语中的数字 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 参数选择合适的复数字符串,第二个 count 参数插入到 %d 占位符中。如果您的复数字符串不包含字符串格式化,则无需将第三个参数传递给 getQuantityString

格式和样式

以下是一些关于如何正确格式化和设置字符串资源样式的重要事项。

处理特殊字符

当字符串包含在 XML 中具有特殊用法的字符时,您必须按照标准 XML/HTML 转义规则转义这些字符。如果您需要转义在 Android 中具有特殊含义的字符,则应使用前导反斜杠。

默认情况下,Android 会将连续的空白字符折叠成单个空格。您可以通过将字符串的相关部分用双引号括起来来避免这种情况。在这种情况下,所有空白字符(包括换行符)将在引号区域内保留。双引号也允许您使用常规的未转义单引号。

字符 转义形式
@ \@
? \?
换行 \n
制表符 \t
U+XXXX Unicode 字符 \uXXXX
单引号 (')

以下任何一种

  • \'
  • 用双引号将整个字符串括起来(例如,"This'll work"
双引号 (") \"

请注意,用单引号将字符串括起来不起作用。

空白字符折叠和 Android 转义发生在资源文件解析为 XML 之后。这意味着 <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);

使用 Spannable 设置样式

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。然后,您可以检索这些注解并使用键和值来应用样式。

创建注解时,请确保将 <annotation> 标记添加到每个 strings.xml 文件中字符串的所有翻译中。


将自定义字体应用于所有语言中的单词“text”

示例 - 添加自定义字体

  1. 添加 <annotation> 标记,并定义键值对。在本例中,键是 font,值是我们想要使用的字体类型: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. 加载字符串资源并查找带有 font 键的注解。然后创建自定义 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 和文本 Parceling

因为 Annotation span 也是 ParcelableSpans,所以键值对会被 Parcel 和 Unparcel。只要 Parcel 的接收者知道如何解释注解,您就可以使用 Annotation span 为 Parcel 的文本应用自定义样式。

要在将文本传递给 Intent Bundle 时保留自定义样式,您首先需要在文本中添加 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);

有关文本样式的更多信息,请参阅以下链接: