Tuesday, February 26, 2013

Distintos background en un mismo TextView




Nuevo Proyecto

Estamos desarrollando un nuevo pet project en la oficina. Voy a comentar como un problema que en principio parece fácil puede complicarse un poco si no conoces a fondo el entorno.

No sólo voy a mostrar la solución al problema, que puede ser más o menos trivial depende del nivel de conocimiento de cada uno, sino también el proceso de la resolución.

Para empezar el proyecto mi compañero diseñó unas pantallas. Al intentar llevar las pantallas a Android me encontré con que no era capaz de dejarla igual a través de los XML.


¿Cuál era el problema?

Mi compañero había escrito una línea a mostrar en el que una de las palabras tenía un color de fondo diferente al del resto, justo como la que acompaña al título índice del post



Cómo en un primer momento no di con una solución fácil decidí dejarlo de lado y realizar la parte de la lógica de la aplicación. Tras un par de horas ya tenía la primera versión de la aplicación. Todo orgulloso fuí a mostrarle el resultado y lo primero que dijo fue:

“Ese no es el diseño que te he pasado yo”

Efectivamente no había puesto el color de fondo a la palabra concreta, puede parecer un tema baladí pero la interfaz de usuario hay que cuidarla bastante, ¿cuántas veces hemos dejado una aplicación con unas características mejores en detrimento de otras simplemente porque la alternativa tiene una interfaz visual más “cool”? Siendo desarrollador me duele reconocerlo, pero he de decir que seguramente más de las que imagino.


Manos a la obra

Tras unos días volví a retomar la tarea con el objetivo principal de copiar el diseño que recibí y llevarlo a la pantalla.

Empecé a meter mano al layout, pero 15 minutos después y tras varias pruebas me dí cuenta que en XML era imposible alcanzar la solución al problema, al menos con mis conocimientos.

Tendría que realizarlo a través de código, así que me lancé a buscar en internet. “Different Backgrounds in the same TextView”, obtuve muchos resultados pero los principales me llevaban a un escenario distinto donde preguntaban cómo poder poner dos colores distintos en un mismo TextView pero refiriéndose al color de la fuente.

En la mayoría de respuestas estaba la función

Html.fromHtml("This is <font color='red'>simple</font>."); 

Esta resuelve la mayoría de los problemas básicos a la hora de dar un formato básico al texto a través de etiquetas Html pero parece que no para el background.

Seguí mi infructuosa búsqueda intentando encontrar alguien que se hubiera enfrentado previamente a mi mismo problema y lo hubiera solucionado, tras realizar en google algunas intentonas me dí cuenta que tendría que enfretarme yo sólo a este problema.


Tirando del hilo(explorando el código fuente)

Me decanté a seguir la pista de distintos colores de fuente en un mismo TextView, así que me embuí a leer el código fuente de Html.fromHtml(String message). Al ser Android un software Open Source no es difícil encontrar algún repositorio que te ofrezca en versión web cualquier archivo bien formateado y con sus colores pero también podemos echarle un vistazo dentro de nuestro ordenador, con la SDK puedes descargarte todo el código fuente así que conociendo el paquete de la clase puedes llegar al código fácilmente.


Busqué allí donde trataba el elemento [<font color=??’>] y observé cuales eran los pasos llevados a cabo. La función fromHtml va haciendo uso de distintas clases de Spannable para ir dando los diferentes formatos y en el caso concreto del color de fuente se hace uso de la clase ForegroundColorSpan. Gracias a las convenciones deduje que podría haber un BackgroundColorSpan, me pasé por al referencia y por allí estaba BackgroundColorSpan, esto me dió buenas sensaciones, tan solo faltaba probarlo.

A pesar de que me he cruzado alguna vez con los Spannable en el código nunca había trabajado anteriormente con ellos.

Así que nada, busqué un ejemplo básico sobre como usar ForegroundColorSpan que parecía estar más solicitado.


Solución

Y realicé la prueba con el BackgroundColorSpan para ver si era justamente lo que andaba buscando. Et voilá.




2 comments:

  1. Muy bueno, y muy curioso. Veo que te lo has tenido que sudar ;-)

    Por cierto, me da la sensación de que has omitido el enlace a la clase BackgroundColorSpan.

    "..., me pasé por al referencia y por allí estaba [enlace],..."

    Gracias por compartirlo.

    ReplyDelete