Android Spanned, SpannedString, Spannable, SpannableString y CharSequence

92

Android ofertas una variedad de interfaces de todas ellas relacionadas con el texto y cadenas: Spanned, SpannedString, Spannable, SpannableStringy CharSequence.

He usado todo lo anterior en varios escenarios, generalmente después de usarlo Html.fromHtml()para mostrar texto enlazable dentro de un TextViewpara aplicarle algo de estilo.

He intentado comprender el propósito / uso de estas interfaces a partir de la documentación oficial de Android y he fallado, ya que es bastante confuso. ¿Cuál es el propósito de estas interfaces? ¿En qué escenarios es más común usarlos? ¿En qué casos es mejor evitar su uso? ¿Hay algún impacto obvio en el rendimiento que deba tenerse en cuenta al utilizar alguno de ellos?

Si alguien pudiera proporcionar una explicación decente, sería muy apreciado.

woot
fuente

Respuestas:

148

¿Cuál es el propósito de estas interfaces?

diagrama de yuml.me/edit/5f8da6cb CharSequencees una interfaz estándar de Java que representa una secuencia de caracteres. Stringes la implementación concreta más utilizada de CharSequence, seguida de StringBuilder.

Spannedes un CharSequencecon "intervalos" que indica el formato que se aplicará a partes del texto, donde esos intervalos no se pueden modificar.

Spannablees a Spanned, agregando la capacidad de modificar los intervalos (para agregar o quitar formato), pero no para modificar el texto en sí.

SpannedStringes una implementación concreta de la Spannedinterfaz.

SpannableStringes una implementación concreta de la Spannableinterfaz.

¿En qué escenarios es más común usarlos?

Cuando hay un método que devuelve uno (por ejemplo, getText()en un EditText) o cuando hay un método que toma uno como parámetro (por ejemplo, setText()en a TextView). diagrama de yuml.me/edit/35c8f39f

Su caso de uso citado Html.fromHtml()es quizás el más común en el desarrollo convencional de Android, ya que un TextViewcon a Spannedes mucho más liviano que un WebView. Sin embargo, existen otros casos de uso, como:

¿En qué casos es mejor evitar su uso?

Son particularmente horribles para combatir la calvicie, quitar la nieve, reparar la bomba de calor, hacer un soufflé, etc.

:-)

¿Hay algún impacto obvio en el rendimiento que deba tenerse en cuenta al utilizar alguno de ellos?

Las interfaces, por definición, no tienen "impactos en el rendimiento", son simplemente una descripción de una API.

No sé que SpannableStringsea ​​significativamente más lento que SpannedStringen cualquier operación en particular. Sin embargo, SpannableStringBuilder(lo que permite manipular el texto además de los intervalos que formatean ese texto) bien puede ser un poco más lento que SpannableStringo SpannedStringpara varias cosas. Sin embargo, si las diferencias de rendimiento son suficientes o no, dependerá del uso.

CommonsWare
fuente
4
Dado que los documentos oficiales están en silencio, ¿cómo obtuviste esta información? ¿Navegación manual de fuentes de la manera más dura?
Pacerier
11
@Pacerier: No estoy seguro de a qué parte de esta respuesta se refiere. Por ejemplo, la jerarquía de clases descrita en esta respuesta ciertamente proviene de la documentación, específicamente los JavaDocs. Por el contrario, la falta de utilidad de estas cosas para combatir la calvicie proviene de la observación personal.
CommonsWare
@CommonsWare, eso significa que una cadena con emoticonos en el medio se consideraría una spannableStringy no una normal ... porque me enfrento a un gran retraso setText(my_string) cuando my_stringtiene emoticones (como la de watsapp) en comparación con una cadena normal. . (que solo tiene texto sin formato) amablemente arroje algo de luz ... de alguna manera creí que los smilleys no son más que texto (unicode) solo
eRaisedToX
1
@eRaisedToX: Los emoticonos se pueden implementar como emoji o imágenes. AFAIK, los emoji serían caracteres Unicode individuales y presumiblemente podrían estar en una cadena regular. Las imágenes requerirían lo ImageSpanque a su vez requiere SpannableString.
CommonsWare
Presumiblemente seguro ... pero intente lidiar con emojis y use cadenas normales y volverá a combatir la calvicie. Editables y SpannableStringBuilders son tus mejores amigos cuando se trata de implementar emojis. Descubrí que, si bien sí, son simplemente unicode, es la forma en que codifica la identificación del intervalo de emoji y la configuración del intervalo de emoji que es donde entra su costo de rendimiento. Tenga cuidado al usar las bibliotecas de emoji de otras personas si no lo sabe cómo funcionan ...
JamisonMan111
43

Cuerda

A Stringes inmutable (es decir, el texto no puede cambiar). Tampoco tiene ningún intervalo asociado. (Los intervalos son rangos sobre el texto que incluyen información de estilo como color, resaltado, cursiva, enlaces, etc.) Por lo tanto, puede usar un Stringcuando su texto no necesita ser cambiado y no necesita ningún estilo.

StringBuilder

A StringBuildertiene texto mutable, por lo que puede modificarlo sin crear un nuevo objeto. Sin embargo, no tiene información sobre el intervalo. Es solo texto sin formato. Por lo tanto, use a StringBuildercuando necesite cambiar el texto, pero no le importa darle estilo.

SpannedString

A SpannedStringtiene texto inmutable (como a String) e información de intervalo inmutable. Es una implementación concreta de los requisitos definidos por la Spannedinterfaz. Use a SpannedStringcuando su texto tenga estilo, pero no necesite cambiar el texto ni el estilo después de su creación.

Nota: No existe tal cosa como un SpannedStringBuilderporque si el texto cambia, es muy probable que la información del intervalo también tenga que cambiar.

SpannableString

A SpannableStringtiene texto inmutable, pero su información de intervalo es mutable. Es una implementación concreta de los requisitos definidos por la Spannableinterfaz. Use a SpannableStringcuando su texto no necesite ser cambiado pero el estilo sí.

SpannableStringBuilder

A SpannableStringBuildertiene tanto texto mutable como información de extensión. Es una implementación concreta de los requisitos definidos por las interfaces Spannabley Editable(entre otros). Utilice a SpannableStringBuildercuando necesite actualizar el texto y su estilo.

CharSequence

A CharSequencees una interfaz y no una clase concreta. Eso significa que solo define una lista de reglas a seguir para cualquier clase que lo implemente. Y todas las clases mencionadas anteriormente lo implementan. Por lo tanto, puede usar un CharSequencecuando desee generalizar el tipo de objeto que tiene para una máxima flexibilidad. Siempre se puede abatido a una Stringo SpannableStringBuildero lo que sea más tarde si es necesario.

Suragch
fuente
3
Aprecio la forma en que presentó su respuesta, muy fácil de leer y entender, gracias
JamisonMan111