Android Spanned, SpannedString, Spannable, SpannableString et CharSequence

92

Android offre une variété d'interfaces toutes liées au texte et des chaînes: Spanned, SpannedString, Spannable, SpannableStringet CharSequence.

J'ai utilisé tout ce qui précède dans divers scénarios généralement après avoir utilisé Html.fromHtml()pour afficher du texte pouvant être lié à l'intérieur d'un TextViewafin de lui appliquer un style.

J'ai essayé de comprendre le but / l'utilisation de ces interfaces à partir de la documentation officielle d'Android et j'ai échoué car c'est assez déroutant. Quel est le but de ces interfaces? dans quels scénarios est-il le plus courant de les utiliser? Dans quels cas est-il préférable d'éviter de les utiliser? Y a-t-il des impacts évidents sur les performances à prendre en compte lors de l'utilisation de l'un d'entre eux?

Si quelqu'un pouvait fournir une explication décente, ce serait très apprécié.

woot
la source

Réponses:

148

Quel est le but de ces interfaces?

diagramme de yuml.me/edit/5f8da6cb CharSequenceest une interface Java standard représentant une séquence de caractères. Stringest la mise en œuvre concrète de CharSequence, suivie de StringBuilder.

Spannedest un CharSequenceavec des "travées" indiquant le formatage à appliquer à des parties du texte, où ces travées ne peuvent pas être modifiées.

Spannableest un Spannedajout de la possibilité de modifier les travées (pour ajouter ou supprimer une mise en forme), mais pas pour modifier le texte lui-même.

SpannedStringest une implémentation concrète de l' Spannedinterface.

SpannableStringest une implémentation concrète de l' Spannableinterface.

dans quels scénarios est-il le plus courant de les utiliser?

Lorsqu'il y a une méthode qui en renvoie un (par exemple, getText()sur un EditText) ou lorsqu'il y a une méthode qui en prend un comme paramètre (par exemple, setText()sur a TextView). diagramme de yuml.me/edit/35c8f39f

Votre cas d'utilisation cité Html.fromHtml()est peut-être le plus courant dans le développement Android conventionnel, car un TextViewavec un Spannedest beaucoup plus léger qu'un WebView. Cependant, il existe d'autres cas d'utilisation, tels que:

Dans quels cas est-il préférable d'éviter de les utiliser?

Ils sont singulièrement terribles pour lutter contre la calvitie, le déneigement, la réparation de la pompe à chaleur, la fabrication d'un soufflé, etc.

:-)

Y a-t-il des impacts évidents sur les performances à prendre en compte lors de l'utilisation de l'un d'entre eux?

Les interfaces, par définition, n'ont pas d '«impact sur les performances» - elles ne sont qu'une description d'une API.

Je ne suis pas conscient que ce SpannableStringsoit beaucoup plus lent que SpannedStringlors d'une opération particulière. Cependant, SpannableStringBuilder(qui permet de manipuler le texte en plus des étendues qui formate ce texte) peut bien être un peu plus lent que SpannableStringou SpannedStringpour diverses choses. Le fait que les différences de performances soient suffisantes ou non dépendra de l'utilisation, cependant.

CommonsWare
la source
4
Puisque les documents officiels sont silencieux, comment avez-vous obtenu ces informations? Source manuelle parcourant la manière hardcore?
Pacerier
11
@Pacerier: Je ne sais pas à quelle partie de cette réponse vous faites référence. Par exemple, la hiérarchie de classes décrite dans cette réponse provient très certainement de la documentation, en particulier des JavaDocs. A l'inverse, le manque d'utilité de ces choses pour lutter contre la calvitie provient d'une observation personnelle.
CommonsWare
@CommonsWare, cela signifie donc qu'une chaîne avec des smileys entre les deux serait considérée comme une spannableStringet non normale .. parce que je suis confronté à un énorme décalage avec setText(my_string) quand my_stringcontient des smileys (comme celui de watsapp) par rapport à une chaîne normale. . (qui n'a que du texte brut) veuillez jeter un peu de lumière ... en quelque sorte, je croyais que les smilleys ne sont rien d'autre que du texte (unicode) seulement
eRaisedToX
1
@eRaisedToX: Smileys peut être implémenté sous forme d'emoji ou d'images. AFAIK, les emoji seraient des caractères Unicode individuels et pourraient vraisemblablement être dans une chaîne régulière. Les images exigeraient ImageSpance qui à son tour exige SpannableString.
CommonsWare
Vraisemblablement sûr ... mais essayez de vous occuper des emojis et d'utiliser des cordes régulières et vous serez de retour à la lutte contre la calvitie. Editables et SpannableStringBuilders sont votre meilleur ami lorsqu'il s'agit d'implémenter des emojis. J'ai trouvé que si oui, ils sont simplement unicode, c'est la façon dont vous codez l'identification de la durée des emojis et le paramètre de la durée des emojis qui est là où votre coût de performance entre en jeu. Faites attention en utilisant les bibliothèques d'emojis d'autres personnes si vous ne savez pas comment ils fonctionnent ...
JamisonMan111
43

Chaîne

A Stringest immuable (c'est-à-dire que le texte ne peut pas changer). Il n'y a pas non plus de portées qui lui sont associées. (Les étendues sont des plages sur le texte qui incluent des informations de style telles que la couleur, la mise en évidence, l'italique, les liens, etc.) Vous pouvez donc utiliser a Stringlorsque votre texte n'a pas besoin d'être modifié et n'a pas besoin de style.

StringBuilder

A StringBuildera un texte modifiable, vous pouvez donc le modifier sans créer un nouvel objet. Cependant, il ne contient aucune information de portée. C'est juste du texte brut. Utilisez donc un StringBuilderlorsque vous avez besoin de modifier le texte, mais que vous ne vous souciez pas du style.

SpannedString

A SpannedStringa un texte immuable (comme a String) et des informations de span immuables. C'est une implémentation concrète des exigences définies par l' Spannedinterface. Utilisez a SpannedStringlorsque votre texte a du style mais que vous n'avez pas besoin de modifier le texte ou le style après sa création.

Remarque: Il n'y a pas de telle chose SpannedStringBuildercar si le texte changeait, les informations de plage devraient également très probablement changer.

SpannableString

A SpannableStringa un texte immuable, mais ses informations d'étendue sont modifiables. C'est une implémentation concrète des exigences définies par l' Spannableinterface. Utilisez a SpannableStringlorsque votre texte n'a pas besoin d'être modifié mais que le style le fait.

SpannableStringBuilder

A SpannableStringBuildera à la fois du texte mutable et des informations d'étendue. Il s'agit d'une implémentation concrète des exigences définies par les interfaces Spannableet Editable(entre autres). Utilisez un SpannableStringBuilderlorsque vous aurez besoin de mettre à jour le texte et son style.

CharSequence

A CharSequenceest une interface et non une classe concrète. Cela signifie qu'il définit simplement une liste de règles à suivre pour toute classe qui l'implémente. Et toutes les classes mentionnées ci-dessus l'implémentent. Vous pouvez donc utiliser un CharSequencelorsque vous souhaitez généraliser le type d'objet dont vous disposez pour une flexibilité maximale. Vous pouvez toujours le réduire à un Stringou SpannableStringBuilderou quoi que ce soit plus tard si vous en avez besoin.

Suragch
la source
3
J'apprécie la façon dont vous avez présenté votre réponse, très facile à lire et à comprendre, merci
JamisonMan111