Android distribuido, SpannedString, Spannable, SpannableString y CharSequence

Android ofrece una variedad de interfaces relacionadas con texto y cadenas: Spanned , SpannedString , Spannable , SpannableString y CharSequence .

He usado todo lo anterior en varios escenarios usualmente después de usar Html.fromHtml() para mostrar texto enlazable dentro de un TextView para aplicarle un poco de estilo.

Intenté 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 usarlos? ¿Hay algún impacto obvio en el rendimiento que deba tenerse en cuenta al utilizar alguno de ellos?

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

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

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

Spanned es una CharSequence con “tramos” que indica que el formato se aplica a partes del texto, donde esos tramos no se pueden modificar.

Spannable es un Spanned , que agrega la capacidad de modificar los tramos (para agregar o quitar formato), pero no para modificar el texto en sí.

SpannedString es una implementación concreta de la interfaz Spanned .

SpannableString es una implementación concreta de la interfaz Spannable .

¿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 un TextView ). diagrama de yuml.me/edit/35c8f39f

El caso citado de utilizar Html.fromHtml() es quizás el más común en el desarrollo de Android convencional, ya que un TextView con un Spanned es mucho más ligero que un WebView . Sin embargo, hay otros casos de uso, como:

  • Destacando los resultados de búsqueda

  • Permitir a los usuarios ingresar texto enriquecido y luego usar Html.toHtml() para conservar ese texto formateado en una versión HTML

¿En qué casos es mejor evitar usarlos?

Son singularmente horribles en combatir la calvicie, la remoción de nieve, la reparación de 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 estoy al tanto de que SpannableString sea ​​significativamente más lento que SpannedString en una operación en particular. Sin embargo, SpannableStringBuilder (que permite manipular el texto además de los tramos que formatean ese texto) bien puede ser un poco más lento que SpannableString o SpannedString para varias cosas. Sin embargo, si las diferencias de rendimiento son suficientes o no dependerá del uso.

Cuerda

Una String es inmutable (es decir, el texto no puede cambiar). Tampoco tiene ningún tramo asociado. (Los espacios se extienden sobre el texto que incluyen información de estilo como color, resaltado, cursiva, enlaces, etc.). De modo que puede usar un String cuando su texto no necesita ser modificado y no necesita ningún estilo.

StringBuilder

Un StringBuilder tiene texto mutable, por lo que puede modificarlo sin crear un nuevo objeto. Sin embargo, no tiene información de intervalo. Es solo texto simple Así que usa un StringBuilder cuando necesites cambiar el texto, pero no te importa diseñarlo.

SpannedString

Un SpannedString tiene texto inmutable (como una String ) y la información de tramo inmutable. Es una implementación concreta de los requisitos definidos por la interfaz Spanned . Utilice SpannedString cuando su texto tenga estilo, pero no necesita cambiar el texto o el estilo una vez creado.

Nota: No existe un SpannedStringBuilder porque si el texto cambia, la información del intervalo también tendría que cambiar.

SpannableString

Un SpannableString tiene texto inmutable, pero su información de extensión es mutable. Es una implementación concreta de los requisitos definidos por la interfaz Spannable . Use SpannableString cuando su texto no necesita ser cambiado, pero sí el estilo.

SpannableStringBuilder

Un SpannableStringBuilder tiene tanto texto mutable como información de tramo. Es una implementación concreta de los requisitos definidos por las interfaces Spannable y Editable (entre otras). Use un SpannableStringBuilder cuando necesite actualizar el texto y su estilo.

CharSequence

Una CharSequence es una interfaz y no una clase concreta. Eso significa que solo define una lista de reglas a seguir para cualquier clase que la implemente. Y todas las clases mencionadas anteriormente lo implementan. Entonces puede usar una CharSequence cuando quiera generalizar el tipo de objeto que tiene para obtener la máxima flexibilidad. Siempre puedes SpannableStringBuilder a String o SpannableStringBuilder o lo que sea más adelante si es necesario.