【问题标题】:Android Spanned, SpannedString, Spannable, SpannableString and CharSequenceAndroid Spanned、SpannedString、Spannable、SpannableString 和 CharSequence
【发布时间】:2013-07-06 23:37:58
【问题描述】:

Android 提供了各种与文本和字符串相关的界面: SpannedSpannedStringSpannableSpannableStringCharSequence

在使用Html.fromHtml()TextView 内显示可链接文本以便对其应用一些样式之后,我在各种场景中通常使用了上述所有方法。

我试图从 Android 的官方文档中了解这些接口的用途/用法,但失败了,因为它非常令人困惑.. 这些接口的目的是什么?在哪些情况下最常使用它们?在哪些情况下最好避免使用它们?使用其中任何一种时,是否有任何明显的性能影响需要考虑?

如果有人能提供一个体面的解释,将不胜感激。

【问题讨论】:

    标签: android textview


    【解决方案1】:

    这些接口的用途是什么?

    CharSequence 是表示字符序列的标准 Java 接口。 StringCharSequence最常用的具体实现,其次是StringBuilder

    Spanned 是一个带有“spans”的CharSequence,表示应用于文本部分的格式,这些span 不能被修改。

    Spannable 是一个Spanned,添加了修改跨度(添加或删除格式)的功能,但不能修改文本本身。

    SpannedStringSpanned 接口的具体实现。

    SpannableStringSpannable 接口的具体实现。

    在哪些场景中最常使用它们?

    当存在返回 1 的方法时(例如,EditText 上的 getText())或当存在将 1 作为参数的方法时(例如,TextView 上的 setText())。

    您引用的使用Html.fromHtml() 的案例可能是传统Android 开发中最常见的,因为TextViewSpanned 的重量比WebView 轻得多。但是,还有其他用例,例如:

    在哪些情况下最好避免使用它们?

    它们在对抗脱发、除雪、热泵维修、制作蛋奶酥等方面非常糟糕。

    :-)

    在使用其中任何一种时,是否有任何明显的性能影响需要考虑?

    根据定义,接口没有“性能影响”——它们只是对 API 的描述。

    我不知道SpannableString 在任何特定操作中都比SpannedString 慢得多。然而,SpannableStringBuilder(除了格式化文本的 span 外,还允许操作文本)可能比SpannableStringSpannedString 慢一些。不过,性能差异是否足够重要将取决于使用情况。

    【讨论】:

    • 由于官方文档是沉默的,您是如何获得这些信息的?手动源码浏览硬核方式?
    • @Pacerier:我不确定您指的是这个答案的哪一部分。例如,这个答案中描述的类层次结构肯定来自文档,特别是 JavaDocs。相反,这些东西在对抗秃发方面缺乏效用来自个人观察。
    • @CommonsWare,这是否意味着中间有笑脸的字符串将被视为spannableString 而不是正常的..因为当@987654355 时我面临setText(my_string) 的巨大滞后@ 与普通字符串相比,其中有笑脸(如 watsapp 的笑脸)..(只有纯文本)请放一些光......不知何故,我相信笑脸只是文本(unicode)而已
    • @eRaisedToX:笑脸可以实现为表情符号或图像。 AFAIK,表情符号将是单独的 Unicode 字符,并且可能在常规字符串中。图片需要ImageSpan,而后者又需要SpannableString
    • 大概可以确定...但是尝试处理表情符号并使用常规字符串,您将立即恢复与秃头作斗争。在实现表情符号时,Editables 和 SpannableStringBuilders 是你最好的朋友。我发现虽然是的,它们只是 unicode,但它是你如何编码表情符号跨度的识别和表情符号跨度的设置,这是你的性能成本的来源。如果你不知道,请小心使用其他人的表情符号库它们是如何运作的......
    【解决方案2】:

    String

    String 是不可变的(即文本不能更改)。它也没有任何关联的跨度。 (跨度是文本的范围,包括颜色、突出显示、斜体、链接等样式信息。)因此,当您的文本不需要更改且不需要任何样式时,您可以使用String

    StringBuilder

    StringBuilder 具有可变文本,因此您可以修改它而无需创建新对象。但是,它没有任何跨度信息。它只是纯文本。因此,当您需要更改文本但不关心其样式时,请使用 StringBuilder

    SpannedString

    SpannedString 具有不可变的文本(如 String)和不可变的跨度信息。它是Spanned 接口定义的需求的具体实现。当您的文本具有样式但您不需要更改文本或创建后的样式时,请使用 SpannedString

    注意: 没有 SpannedStringBuilder 这样的东西,因为如果文本更改,那么跨度信息也很可能必须更改。

    SpannableString

    SpannableString 具有不可变的文本,但其跨度信息是可变的。它是Spannable 接口定义的需求的具体实现。当您的文本不需要更改但样式需要更改时,请使用 SpannableString

    SpannableStringBuilder

    SpannableStringBuilder 具有可变文本和跨度信息。它是SpannableEditable 接口(以及其他接口)定义的要求的具体实现。当您需要更新文本及其样式时,请使用SpannableStringBuilder

    CharSequence

    CharSequence 是一个接口,而不是一个具体的类。这意味着它只是为实现它的任何类定义了要遵循的规则列表。上面提到的所有类都实现了它。因此,当您想概括您拥有的对象类型以获得最大灵活性时,您可以使用CharSequence。如果需要,您可以随时将其转换为 StringSpannableStringBuilder 或其他任何名称。

    【讨论】:

    • 我很欣赏您的回复方式,非常易于阅读和理解,谢谢
    猜你喜欢
    • 2017-09-02
    • 2011-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多