Android Spanned,SpannedString,Spannable,SpannableString和CharSequence

Android提供了各种与文本和string相关的接口: SpannedStringSpannableSpannableStringSpannableStringCharSequence

通常在使用Html.fromHtml()TextView中显示可链接的文本之后,在各种场景中使用了上述所有方法,以便将某些样式应用于TextView

我试图从Android的官方文档中了解这些接口的用途和用法,并且因为这是相当混乱的而失败了。这些接口的用途是什么? 在哪种情况下使用它们大多是常见的? 在哪种情况下最好避免使用它们? 在使用其中任何一个时,是否有任何明显的性能影响?

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

这些接口的目的是什么?

来自yuml.me/edit/5f8da6cb的图表 CharSequence是表示一系列字符的标准Java接口。 StringCharSequence的最常用的具体实现,其次是StringBuilder

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

SpannableSpannable ,增加了修改跨度(添加或删除格式)的function,但不能修改文本本身。

SpannedStringSpannedString接口的具体实现。

SpannableStringSpannable接口的具体实现。

在哪种情况下使用它们大多是常见的?

当有一个方法返回一个(例如,在EditText上的getText() ),或者当有一个方法以一个参数为参数(例如,在TextView上的setText() )。 来自yuml.me/edit/35c8f39f的图表

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

  • 突出显示search结果

  • 允许用户input富文本 ,然后使用Html.toHtml()在HTML格式的文本中保留该格式的文本

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

他们在打击秃顶,除雪,热泵维修,制作蛋奶酥等方面独一无二。

🙂

在使用其中任何一个时,是否有任何明显的性能影响?

根据定义,接口不具有“性能影响” – 它们仅仅是对API的描述。

我不知道在任何特定的操作SpannedStringSpannedString显着慢。 但是, SpannableStringBuilder (允许处理除了格式化文本的跨度之外的文本)可能比SpannableStringSpannedString慢一些。 性能差异是否足够重要取决于使用情况。

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

StringBuilder的

一个StringBuilder有可变的文本,所以你可以修改它而不创build一个新的对象。 但是,它没有任何跨度信息。 这只是纯文本。 所以当你需要改变文本的时候使用一个StringBuilder ,但是你不关心样式。

SpannedString

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

注意:没有SpannedStringBuilder这样的事情,因为如果文本改变了,那么跨度信息也很可能不得不改变。

SpannableString

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

SpannableStringBuilder

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

为CharSequence

CharSequence是一个接口,而不是一个具体的类。 这意味着它只是为任何实现它的类定义了一系列规则。 上面提到的所有类都执行它。 所以,如果要概括最大灵活性的对象types,可以使用CharSequence 。 如果需要的话,你总是可以将它下传到一个String或者SpannableStringBuilder或者其他什么。