Android Spanned, SpannedString, Spannable, SpannableString und CharSequence

90

Android bietet eine Vielzahl von Schnittstellen alle im Zusammenhang mit Text und Strings: Spanned, SpannedString, Spannable, SpannableStringund CharSequence.

Ich habe all das in verschiedenen Szenarien verwendet, normalerweise nachdem ich Html.fromHtml()verlinkbaren Text in einem angezeigt habe TextView, um ihm etwas Stil zu verleihen.

Ich habe versucht, den Zweck / die Verwendung dieser Schnittstellen aus der offiziellen Dokumentation von Android zu verstehen, und bin gescheitert, da dies ziemlich verwirrend ist. Was ist der Zweck dieser Schnittstellen? In welchen Szenarien werden sie meistens verwendet? In welchen Fällen ist es am besten, sie nicht zu verwenden? Gibt es offensichtliche Auswirkungen auf die Leistung, die bei der Verwendung einer dieser Faktoren zu berücksichtigen sind?

Wenn jemand eine anständige Erklärung liefern könnte, wäre er sehr dankbar.

woot
quelle

Antworten:

146

Was ist der Zweck dieser Schnittstellen?

Diagramm von yuml.me/edit/5f8da6cb CharSequenceist eine Standard-Java-Schnittstelle, die eine Folge von Zeichen darstellt. Stringist die am häufigsten verwendete konkrete Implementierung von CharSequence, gefolgt von StringBuilder.

Spannedist ein CharSequencemit "Bereiche", der die Formatierung angibt, die auf Teile des Textes angewendet werden soll, in denen diese Bereiche nicht geändert werden können.

Spannableist eine Spanned, die die Möglichkeit hinzufügt, die Bereiche zu ändern (Formatierung hinzuzufügen oder zu entfernen), aber den Text selbst nicht zu ändern.

SpannedStringist eine konkrete Implementierung der SpannedSchnittstelle.

SpannableStringist eine konkrete Implementierung der SpannableSchnittstelle.

In welchen Szenarien werden sie meistens verwendet?

Wenn es eine Methode gibt, die eine zurückgibt (z. B. getText()bei einer EditText), oder wenn es eine Methode gibt, die eine als Parameter verwendet (z. B. setText()bei a TextView). Diagramm aus yuml.me/edit/35c8f39f

Ihr zitierter Fall der Verwendung Html.fromHtml()ist vielleicht der häufigste in der konventionellen Android-Entwicklung, da ein TextViewmit a Spannedviel leichter ist als ein WebView. Es gibt jedoch auch andere Anwendungsfälle wie:

In welchen Fällen ist es am besten, sie nicht zu verwenden?

Sie sind besonders schrecklich bei der Bekämpfung von Kahlheit, Schneeräumung, Reparatur von Wärmepumpen, Herstellung eines Soufflés usw.

:-)

Gibt es offensichtliche Auswirkungen auf die Leistung, die bei der Verwendung einer dieser Faktoren zu berücksichtigen sind?

Schnittstellen haben per Definition keine "Auswirkungen auf die Leistung" - sie sind lediglich eine Beschreibung einer API.

Mir ist nicht bewusst, dass dies SpannableStringwesentlich langsamer ist als SpannedStringbei einer bestimmten Operation. Allerdings SpannableStringBuilder(was das Bearbeiten des Textes zusätzlich zu den Bereichen ermöglicht, in denen dieser Text formatiert wird) kann jedoch etwas langsamer sein als SpannableStringoder SpannedStringfür verschiedene Dinge. Ob die Leistungsunterschiede ausreichen, hängt jedoch von der Verwendung ab.

CommonsWare
quelle
4
Wie haben Sie diese Informationen erhalten, da die offiziellen Dokumente schweigen? Manuelles Quellenbrowsen auf Hardcore-Art?
Pacerier
11
@ Pacerier: Ich bin nicht sicher, auf welchen Teil dieser Antwort Sie sich beziehen. Die in dieser Antwort beschriebene Klassenhierarchie stammt beispielsweise mit Sicherheit aus der Dokumentation, insbesondere aus den JavaDocs. Umgekehrt beruht der Mangel an Nützlichkeit dieser Dinge zur Bekämpfung der Kahlheit auf persönlicher Beobachtung.
CommonsWare
@CommonsWare, bedeutet das auch, dass eine Zeichenfolge mit dazwischen liegenden Smileys als eine spannableStringund keine normale angesehen wird. Ich habe eine große Verzögerung, setText(my_string) wenn my_stringSmileys (wie die von WatsApp) im Vergleich zu normalen Zeichenfolgen enthalten sind. . (der nur einfachen Text enthält) werfen Sie bitte etwas Licht ... irgendwie glaubte ich, dass Smilleys nichts als Text (Unicode) sind
eRaisedToX
1
@eRaisedToX: Smileys können als Emoji oder Bilder implementiert werden. AFAIK, Emoji wären einzelne Unicode-Zeichen und könnten sich vermutlich in einer regulären Zeichenfolge befinden. Bilder würden erfordern, ImageSpanwas wiederum erfordert SpannableString.
CommonsWare
Vermutlich sicher ... aber versuchen Sie, mit Emojis umzugehen und normale Strings zu verwenden, und Sie werden gleich wieder gegen Kahlheit vorgehen. Editables und SpannableStringBuilders sind Ihre besten Freunde, wenn es um die Implementierung von Emojis geht. Ich habe festgestellt, dass sie zwar einfach Unicode sind, aber wie Sie die Identifizierung der Emoji-Spanne und die Einstellung der Emoji-Spanne codieren, in der Ihre Leistungskosten anfallen. Verwenden Sie die Emoji-Bibliotheken anderer Leute vorsichtig, wenn Sie es nicht wissen wie sie funktionieren ...
JamisonMan111
42

String

A Stringist unveränderlich (dh der Text kann sich nicht ändern). Es sind auch keine Bereiche zugeordnet. (Bereiche sind Bereiche über dem Text, die Stilinformationen wie Farbe, Hervorhebung, Kursivschrift, Links usw. enthalten.) Sie können also a verwenden, Stringwenn Ihr Text nicht geändert werden muss und kein Stil benötigt.

StringBuilder

A StringBuilderhat veränderlichen Text, sodass Sie ihn ändern können, ohne ein neues Objekt zu erstellen. Es enthält jedoch keine Bereichsinformationen. Es ist nur einfacher Text. Verwenden Sie also a, StringBuilderwenn Sie den Text ändern müssen, sich aber nicht um das Styling kümmern.

SpannedString

A SpannedStringhat unveränderlichen Text (wie a String) und unveränderliche Bereichsinformationen. Es ist eine konkrete Umsetzung der von der SpannedSchnittstelle definierten Anforderungen . Verwenden Sie a, SpannedStringwenn Ihr Text einen Stil hat, Sie jedoch weder den Text noch den Stil nach der Erstellung ändern müssen.

Hinweis: Es gibt keine, SpannedStringBuilderdenn wenn sich der Text ändern würde, müssten sich höchstwahrscheinlich auch die Bereichsinformationen ändern.

SpannableString

A SpannableStringhat unveränderlichen Text, aber seine Bereichsinformationen sind veränderbar. Es ist eine konkrete Umsetzung der von der SpannableSchnittstelle definierten Anforderungen . Verwenden Sie a, SpannableStringwenn Ihr Text nicht geändert werden muss, das Styling jedoch.

SpannableStringBuilder

A SpannableStringBuilderenthält sowohl veränderbare Text- als auch Bereichsinformationen. Es handelt sich um eine konkrete Umsetzung der Anforderungen, die unter anderem durch die Schnittstellen Spannableund definiert werden Editable. Verwenden Sie a, SpannableStringBuilderwenn Sie den Text und seinen Stil aktualisieren müssen.

Zeichenfolge

A CharSequenceist eine Schnittstelle und keine konkrete Klasse. Das heißt, es wird nur eine Liste von Regeln definiert, die für jede Klasse befolgt werden müssen, die sie implementiert. Und alle oben genannten Klassen implementieren es. Sie können also a verwenden, CharSequencewenn Sie den Objekttyp, den Sie haben, für maximale Flexibilität verallgemeinern möchten. Sie können es später jederzeit auf ein Stringoder SpannableStringBuilderoder was auch immer zurückwerfen, wenn Sie müssen.

Suragch
quelle
2
Ich schätze die Art und Weise, wie Sie Ihre Antwort präsentiert haben, sehr einfach zu lesen und zu verstehen, danke
JamisonMan111