Android – Styles & Themes

Logotipo de Android

Hace ya un tiempo que comencé a investigar sobre programación para Android y de toda la información que leí encontré realmente muy poco sobre creación de themes propios para una aplicación. En la documentación oficial se llega a entender bien la parte correspondiente a estilos pero cuando comienza la parte de themes se queda muy corta y al parecer la única manera de aprender es meterse por todos los archivos fuentes de las distintas plataformas de Android y comenzar a ver como lo utilizan para los themes estándares (Theme.Holo, Theme.Holo.Light, Theme.Holo.Light.DarkActionBar).

Después de horas y horas intentando entender los archivos XML haciendo pruebas y cometiendo errores puedo concluir en que realmente sería mucho más sencillo si la documentación oficial explicara al menos lo que voy a intentar explicar en este artículo ya que una vez que se entiende resulta relativamente sencillo. De todas maneras como fanático de Google, entiendo que Android crece días tras día un poco más y confío en que dentro de poco tiempo vayan actualizando la documentación haciéndonos la vida un poco más fácil.

Antes de seguir leyendo te recomiendo que le des una leída a la documentación oficial de Android.

¿Qué diferencia hay entre Styles y Themes?

Realmente cuando vemos el código nos damos cuenta que en realidad, programáticamente, son las mismas cosas ya que para ambos se utilizan estilos pero, conceptualmente, los estilos están pensados para modificar la apariencia de un View específicamente como por ejemplo modificar el tamaño, color, background, padding, etc de un TextView o un EditText. Es decir que los estilos sirven como el CSS para los componentes (TAGs) HTML.

Cuando hablamos de Themes, no hablamos de cambiar la apariencia de un View en particular sino que hablamos de aplicar un estilo a un Activity o a toda la aplicación. En otras palabras, los themes se utilizan para mantener un estilo de diseño equivalente entre los distintos activities y hacer que una aplicación se vea igual a medida que la vayamos usando.

Es probable que estén pensando que si crean un estilo por ejemplo para un TextView podrían aplicar el estilo a todos los TextViews de la aplicación y lograrían lo mismo que haciendo con un Theme, a lo que contestaría que tienen toda la razón. La gran diferencia que yo note es que si quiero que todos los TextViews sean iguales, ¿por qué debería estar aplicando manualmente los estilos?, yo preferiría hacerlo en forma global.

Si tomamos en cuenta CSS podríamos decir que los estilos serían equivalentes a crear una clase (class) mientras que un theme sería utilizar las etiquetas HTML para aplicar estilos globales. Tomemos como ejemplo la idea de cambiar el estilo y color estándar a los párrafos de un sitio.

[css highlight=»1″]
.nuevo_estilo_parrafo{
font-size: 1em;
color: #c0c0c0;
}
[/css]

Una vez que tengo el estilo, lo aplicamos a los párrafos para que se muestren con el diseño definido:

[html]
<body>
<p class="nuevo_estilo_parrafo">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p class="nuevo_estilo_parrafo">Curabitur vitae libero sit amet metus hendrerit cursus at ac nulla.</p>
<p class="nuevo_estilo_parrafo">Sed malesuada posuere metus volutpat consectetur.</p>
<p class="nuevo_estilo_parrafo">Mauris porta elementum malesuada. Curabitur ornare tincidunt adipiscing. </p>
<p class="nuevo_estilo_parrafo">Vivamus nec dapibus tellus. Vestibulum id dictum lectus.</p>
</body>
[/html]

Aquí nos damos cuenta que en realidad si quisiéramos aplicar el mismo estilos a todos los párrafos entonces deberíamos crear un estilo para la etiqueta “P” y utilizar las clases solamente para los párrafos especiales a los que queramos que tengan un estilo diferente al estándar creado por nosotros. Para esto crearíamos el estilo y no aplicamos más clases a los párrafos ya que al ser un estilo global se aplicará automáticamente:

[css htmlscript=»true»]
p{
font-size: 1em;
color: #c0c0c0;
}

.nuevo_estilo_parrafo{
font-size: 1em;
color: #ff0000;
}

<body>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Curabitur vitae libero sit amet metus hendrerit cursus at ac nulla.</p>
<p>Sed malesuada posuere metus volutpat consectetur.</p>
<p class="nuevo_estilo_parrafo">Mauris porta elementum malesuada. Curabitur ornare tincidunt adipiscing. </p>
<p>Vivamus nec dapibus tellus. Vestibulum id dictum lectus.</p>
</body>
[/css]

Como lo pueden ver ahora solo el cuarto párrafo tiene un estilo propio y esta es la idea justamente en Android. Cuando queremos cambiar globalmente el diseño de un TextView, EditText, etc. deberíamos usar un Theme y aplicarlo globalmente a un Activity o a la aplicación completa mientras que si queremos modificar el diseño de uno o algunos Views en especial utilicemos estilos.

¿Como crear y aplicar estilos?

Para crear estilos tenemos que crear un archivo XML dentro de la carpeta values/ por ejemplo con el nombre styles.xml

[xml highlight=»4,5,6,7″ title=»Archivo: /res/values/styles.xml»]
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">

<style name="big_red">
<item name="android:textSize">30sp</item>
<item name="android:textColor">@color/red</item>
</style>

</resources>
[/xml]

Para que compile asegúrate de crear el color para lo que tienes que crear por ejemplo un archivo colors.xml dentro de la carpeta values/ con la siguiente línea:

[xml highlight=»4″ title=»Archivo: /res/values/colors.xml»]
<?xml version="1.0" encoding="utf-8"?>
<resources>

<color name="red">#ff0000</color>

</resources>
[/xml]

Observación: También podrías crear el color dentro del mismo archivo styles.xml pero queda más ordenado tener todos los colores en un archivo.

Con esto ya tenemos un estilo que podemos aplicar por ejemplo a un TextView de la siguiente manera en el layout que desees:

[xml highlight=»2″ title=»Archivo: /res/layout/activity_main.xml»]
<TextView
style="@style/big_red"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/texto_prueba" />
[/xml]

Aquí tampoco tienes que olvidar crear el texto en el archivo string.xml de la carpeta values/. Esto es una buena práctica para que después puedas hacer que tu aplicación sea internacionalizable.

Ahora bien, con relación a los atributos que podemos utilizar para los estilos es bien simple, puedes utilizar los atributos que utilizas al definir un View en el layout. Inclusive puedas usar como estilos los atributos android:layout_width y android:layout_height lo cual te ayuda a dejar más pequeño tu layout (esto no lo puedes hacer con los themes ya que por más que los pongas en el layout no lo reconoce y pide que lo pongas ahí)

¿Como crear y aplicar themes?

Para crear los temas, como expliqué más arriba, también se utilizan estilos pero en lugar de usar el archivo values/styles.xml crearemos uno llamado themes.xml solo para separar los conceptos:

[xml highlight=»4″ title=»Archivo: /res/values/themes.xml»]
<?xml version="1.0" encoding="utf-8"?>
<resources>

<style name="CustomTheme"></style>

</resources>
[/xml]

Con esto hemos creado un tema llamado CustomTheme. Como lo puedes ver es simplemente un estilo pero a la hora de aplicarlo lo tendrías que aplicar a un Activity o a la aplicación en forma global y esto lo haces en el archivo AndroidManifest.xml de la siguiente manera:

En caso de querer aplicarlo a un o unos Activities específicos:

[xml highlight=»7″ title=»Archivo: AndroidManifest.xml»]
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main"
android:theme="@style/CustomTheme" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
[/xml]

En caso de querer aplicarlo a nivel global:

[xml highlight=»7″ title=»Archivo: AndroidManifest.xml»]
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/CustomTheme" >
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
[/xml]

Ahora bien, con esto hemos creado un tema desde cero pero si quisiéramos por ejemplo hacer que herede el diseño estándar de otro tema como para no trabajar desde cero sería también muy sencillo.

Como ves en el atributo android:theme=”” ponemos el nombre del tema que queremos usar. Si por ejemplo quisiéramos usar el tema por defecto de Ice Cream Sandwitch “Holo”, en lugar de poner @styles/CustomTheme deberíamos poner android:theme=”@android:style/Theme.Holo” o cualquiera de sus alteraciones “Theme.Holo.Light”, “Theme.Holo.Light.DarkActionBar”, “Theme.Holo.Light.NoActionBar”, etc.

Ya que sabemos esto lo que haremos será hacer que nuestro CustomTheme herede todo lo equivalente de Theme.Holo.Light para trabajar sobre algo completo e ir cambiando los detalles según vayamos necesitando. Para esto volvemos a nuestro archivo themes.xml y agregamos el siguiente código:

[xml highlight=»4″ title=»Archivo: res/values/themes.xml»]
<?xml version="1.0" encoding="utf-8"?>
<resources>

<style name="CustomTheme" parent="android:Theme.Light"></style>

</resources>
[/xml]

Con esto le decimos a nuestro tema que herede todas las propiedades del tema “android:Theme.Light”. Puedes ir cambiando las posibilidades y lo vas probando para ver los cambios.

La parte complicada: Entender los temas

Hasta esta parte fue nada más que una introducción al propósito real de este artículo ya que hasta aquí es información que encontramos en la documentación oficial y googleando un poco. Insisto que esto es complicado por la falta de documentación y no así por la forma de crear los temas.

Observación: Repito que es muy importante que lean y entiendan la documentación oficial, por más que no es muy detallada les dará la base a los que necesitamos para esta sección del artículo

Así como vimos, los estilos que creamos pueden tener los atributos que usamos al crear los Views en nuestros layouts, pero existen otros atributos que definen cual sería el estilo por defecto de un View o componente y estos deberíamos usarlos para nuestros temas. Tomando como ejemplo lo que vimos de HTML y CSS, necesitamos alguna forma de decir cual será el estilo estándar por ejemplo para un TextView como era el caso de nuestros estilos por defecto para la etiqueta “P”.

Hay varios atributos que ya existen como por ejemplo android:textViewStyle, android:buttonStyle, android:listViewStyle a los cuales se les indica que estilo creado por nosotros sería el que tiene que aplicarse y esta es la parte realmente complicada para mi gusto ya que hay muy poca información sobre esto y la forma de aprender, hoy en día al menos, es explorando los archivos XML de Android para entender como funcionan sus temas por defecto.

Para poder ver los archivos fuentes de Android con relación a los resources los podremos encontrar dentro del SDK en la carpeta platforms/. Dentro de esta carpeta se descargan los archivos para todas las plataformas de android que seleccionamos al momento de la instalación con el “Android SDK Manager” por ejemplo:

  • 2.2 – Froyo – API 8
  • 2.3.3 – Gingerbread – API 10
  • 4.0.3 – Ice Cream Sandwitch – API 15
  • 4.1 – Jelly Bean – API 16

Como vamos a trabajar para este ejemplo usando como base el tema HOLO que apareció desde Ice Cream Sandwitch usaremos los archivos que se encuentra en al carpeta platforms/android-15 y dentro de esta carpeta, los recursos se encuentran en platforms/android-15/data/res.

Al ingresar podrán ver todas las imágenes, estilos, temas, colores, atributos, animaciones, menues, strings por defecto de la versión ICS para todas las resoluciones, idiomas y combinaciones posibles.

De todos estos archivos nos basaremos en tres que serían los más importantes para aprender como se utilizan los temas.

  1. values/attrs.xml
  2. values/themes.xml
  3. values/styles.xml

Por ejemplo para ver cuales son los estilos de un TextView buscamos dentro del archivo attr.xml lo que haya referente a TextView. Aquí estarían definidos los atributos que podemos utilizar y encontramos el atributo textViewStyle:

[xml title=»Archivo: %ANDROID_SDK%/platforms/android-15/data/res/values/attr.xml»]
<!– Default TextView style. –>
<attr name="textViewStyle" format="reference" />
[/xml]

Ahora que ya sabemos que este atributo es para el estilo por defecto de los TextViews lo iremos a buscar en el archivo themes.xml y encontraremos esta línea:

[xml title=»Archivo: %ANDROID_SDK%/platforms/android-15/data/res/values/themes.xml»]
<item name="textViewStyle">@android:style/Widget.TextView</item>
[/xml]

Con esto vemos que para este theme los estilos definidos para este atributo están definidos en los estilos de android bajo el nombre de Widget.TextView por lo que iremos al archivo styles.xml a buscarlo y encontramos lo siguiente:

[xml title=»Archivo: %ANDROID_SDK%/platforms/android-15/data/res/values/styles.xml»]
<style name="Widget.TextView">
<item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
<item name="android:textSelectHandleLeft">?android:attr/textSelectHandleLeft</item>
<item name="android:textSelectHandleRight">?android:attr/textSelectHandleRight</item>
<item name="android:textSelectHandle">?android:attr/textSelectHandle</item>
<item name="android:textEditPasteWindowLayout">?android:attr/textEditPasteWindowLayout</item>
<item name="android:textEditNoPasteWindowLayout">?android:attr/textEditNoPasteWindowLayout</item>
<item name="android:textEditSidePasteWindowLayout">?android:attr/textEditSidePasteWindowLayout</item>
<item name="android:textEditSideNoPasteWindowLayout">?android:attr/textEditSideNoPasteWindowLayout</item>
<item name="android:textEditSuggestionItemLayout">?android:attr/textEditSuggestionItemLayout</item>
<item name="android:textCursorDrawable">?android:attr/textCursorDrawable</item>
</style>
[/xml]

Aquí podemos llegar a tener referencias a otros estilos o a otros atributos. En este último paso tenemos que ir siguiéndolos hasta encontrar los estilos. Por ejemplo vemos el primer donde notamos que hace referencia al atributo textAppearanceSmall. Esta es la razón por la que si en el eclipse vamos a nuestro layout y desde el panel de Form Widgets agregamos un TextView (el más sencillo y no los que dicen Large, Medium, Small) dentro de nuestro layout y vemos en el panel de propiedades, notaremos que sobre la propiedad “Text Appearance” está vinculado a “?android:attr/textAppearanceSmall”.

Ahora bien, si queremos ver que es este textAppearanceSmall iremos nuevamente a nuestro archivo attr.xml donde encontramos un comentario que dice “Default appearance of text: color, typeface, size, and style.” es decir los formatos básicos para los textos y si queremos saber el estilo al que apunta en el tema vemos en el archivo themes.xml que hace referencia a “@android:style/TextAppearance”, el cual encontraremos en styles.xml

[xml title=»Archivo: %ANDROID_SDK%/platforms/android-15/data/res/values/styles.xml»]
<style name="TextAppearance">
<item name="android:textColor">?textColorPrimary</item>
<item name="android:textColorHighlight">?textColorHighlight</item>
<item name="android:textColorHint">?textColorHint</item>
<item name="android:textColorLink">?textColorLink</item>
<item name="android:textSize">16sp</item>
<item name="android:textStyle">normal</item>
</style>
[/xml]

Donde vemos que están definidos los colores, tamaño y estilo de fuente. Como podrán ver los items que empiezan con ? serán otros atributos.

En resumen, un atributo creado en attr.xml tiene una definición en el archivo themes.xml que referencia al estilo que se encontrará en styles.xml. Este último a su vez puede contener otros atributos en cuyo caso debemos ir siguiendo las pistas para poder ver finalmente cuales son sus estilos finales.

Estándares encontrados en mi investigación

Como sabrán, siempre es bueno tener estándares dentro del mundo de la programación y para esto, según vemos en los fuentes, podremos encontrar unos estándares rápidos.

Primeramente algo que me parece útil es que en las plataformas de Android vemos unos atributos (attr.xml) para el manejo por defecto de los colores de la aplicación. Para esto encontraremos tres atributos

  1. textColorPrimary
  2. textColorSecondary
  3. textColorTertiary

Estos atributos serían las referencias a tres colores, en este caso para las aplicaciones por defecto. Uno que sería el color primario o principal, otro para un segundo color y otro para un tercer color. Lo interesante es que el resto de los atributos no hacen referencia directamente a los colores sino que hacen referencia a uno de estos atributos. Y para tener opciones tendremos los siguientes tres:

  1. textColorPrimaryInverse
  2. textColorSecondaryInverse
  3. textColorTertiaryInverse

Por ejemplo si el color principal de la aplicación es un azul y ahora queremos poner ese azul sobre un fondo oscuro donde no se notaría bien usamos el inverso que sería un celeste o un color claro para esos casos. Esto se utiliza mucho para tener un tema oscuro (Dark) y uno claro (Light).

Ejemplo – CustomTheme

Ahora bien, ¿como creamos los estilos para nuestro CustomTheme?

Para este ejemplo crearemos un proyecto Android nuevo y al crear nuestro tema como lo vimos arriba, haremos que herede del tema por defecto “android:Theme.Holo.Light.DarkActionBar” para ir viendo como cambian las cosas sin tener que escribirlo desde cero. Para esto crearemos un archivo themes.xml y escribiremos el siguiente código:

[xml highlight=»4″ title=»Archivo: /res/values/themes.xml»]
<?xml version="1.0" encoding="utf-8"?>
<resources>

<style name="CustomTheme" parent="android:Theme.Light"></style>

</resources>
[/xml]

Para hacer bien notorios los cambios vamos a crear ya un archivo para los colores, los cuales serán bien notorios. Para esto creamos el archivo colors.xml

[xml highlight=»4,5,6,7″ title=»Archivo: /res/values/colors.xml»]
<?xml version="1.0" encoding="utf-8"?>
<resources>

<color name="red">#ff0000</color>
<color name="green">#00ff00</color>
<color name="blue">#0000ff</color>
<color name="black">#000000</color>

</resources>
[/xml]

También para notar los cambios, crearemos un layout en el agregaremos cuatro TextViews.

[xml highlight=»7,8,9,10,11,12,14,15,16,17,18,19,21,22,23,24,25,26,28,29,30,31,32″ title=»Archivo: /res/layout/activity_main.xml»]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />

<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />

<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall" />

<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />

</LinearLayout>
[/xml]

Esto resultaría en una pantalla como la siguiente:

Ejemplo del Activity creado arriba

Como podrán notar, lo que hice fue elegir cuatro TextViews de la paleta de componentes “FormWidgets”. Uno para cada una de las opciones: Large, Medium, Small y TextView. En el código notarán que la diferencia será el TextAppearance que se puede notar en el panel de propiedades cuando hacen click sobre cada TextView. Verán que un principio todos son negros y la diferencia está en el tamaño y si se fijan en el TextAppearance de cada uno verán que apuntan a ?android:attr/textAppearanceLarge, ?android:attr/textAppearanceMedium, ?android:attr/textAppearanceSmall y que el que no tiene definido nada en el XML del layout tambień apunta a ?android:attr/textAppearanceSmall, esto último por lo que vimos más arriba.

Ahora bien, vamos a cambiar los estilos por defecto de los textos y para esto tenemos cuatro atributos definidos ya que podemos reutilizar

  • android:textAppearance: define el estilo estándar para los textos normales
  • android:textAppearanceLarge: define el estilo estándar para los textos grandes. Podría ser utilizado para los títulos principales, lo que sería un <h1> en HTML
  • android:textAppearanceMedium: define el estilo estándar para los textos de mediano tamaño. Podría ser utilizado para los títulos de segundo nivel, lo que sería un <h2> en HTML
  • android:textAppearanceSmall: define el estilo estándar para los textos pequeños. Podría ser utilizado para textos pequeños como por ejemplo textos menores al texto normal que utilizaríamos (android:textAppearance)

Observación: Por más que estos 4 atributos ya existen dentro del tema Holo que estamos heredando, en este caso “Theme.Holo.Light.DarkActionBar” la forma en que lo defino arriba es un ejemplo ya que ustedes pueden utilizarlos con el concepto que necesiten.

Ahora, tenemos que definir por cada uno de los cuatro atributos de arriba, cual estilo creado por nosotros será el que contendrá la definición para ese atributo. Todo lo que indique referenciar cual estilo será el aplicado a un atributo específico lo mantendré dentro del archivo themes.xml mientras que los estilos que no sean estándares los pondré dentro del archivo styles.xml por lo que escribiremos el siguiente código dentro del archivo themes.xml

[xml highlight=»7,8,9,10,15,16,17,18,20,21,22,23,25,26,27,29,30,31,32″ title=»Archivo: /res/values/themes.xml»]
<?xml version="1.0" encoding="utf-8"?>
<resources>

<style name="CustomTheme" parent="android:Theme.Holo.Light.DarkActionBar">

<!– Text styles –>
<item name="android:textAppearance">@style/CustomTheme.TextAppearance</item>
<item name="android:textAppearanceSmall">@style/CustomTheme.TextAppearance.Small</item>
<item name="android:textAppearanceMedium">@style/CustomTheme.TextAppearance.Medium</item>
<item name="android:textAppearanceLarge">@style/CustomTheme.TextAppearance.Large</item>

</style>

<!– Text styles –>
<style name="CustomTheme.TextAppearance" parent="@android:style/TextAppearance">
<item name="android:textColor">@color/black</item>
<item name="android:textSize">16sp</item>
</style>

<style name="CustomTheme.TextAppearance.Small" parent="@android:style/TextAppearance.Small">
<item name="android:textColor">@color/blue</item>
<item name="android:textSize">10sp</item>
</style>

<style name="CustomTheme.TextAppearance.Medium" parent="@android:style/TextAppearance.Medium">
<item name="android:textColor">@color/green</item>
</style>

<style name="CustomTheme.TextAppearance.Large" parent="@android:style/TextAppearance.Large">
<item name="android:textColor">@color/red</item>
<item name="android:textStyle">bold</item>
</style>

</resources>
[/xml]

Vemos que para el CustomTheme, que hereda de “android:Theme.Holo.Light.DarkActionBar”, vamos a cambiar el estilo por defecto de los cuatro atributos (lineas 7-10). Estos estilos a los que hago referencia son estilos que debemos crearlos más abajo haciendo que hereden de sus correspondientes en Holo para no tener que escribirlos desde cero.

Observación: Los correspondientes estilos en Holo los detecto justamente analizando los archivos que vimos más arriba

Los nombres que elijo para los estilos pueden ser como yo los quiera llamar pero los utilizo siguiendo el estándar de los ya definidos “CustomTheme.TextAppearance.Small”. Esto permite dos cosas muy importantes

  1. Tener varios temas y definir los mismos estilos, por ejemplo: CustomTheme.TextAppearance, CustomTheme2.TextAppearance

  2. Esta sintaxis con puntos es otra forma de implementar la herencia entre estilos. De esta forma el estilo “CustomTheme.TextAppearance.Small” hereda por defecto el contenido de “CustomTheme.TextAppearance” y me permite redefinir sus atributos. En este caso no heredaría los atributos porque hereda también de parent=”@android:style/TextAppearance.Small” por lo cual tiene precedencia.

Ahora tendremos que aplicar el tema a nuestra aplicación por medio del archivo AndroidManifest.xml como lo vimos arriba y el resultado de la vista debería ser así:

Pantalla de ejemplo con los cambios realizados

Ahora cada vez que use los TextViews de la paleta de FormWidget por defecto se verán así porque hemos delegado el estilo dentro del tema.

Ahora haremos que el texto normal que usamos no sea con el TextAppearanceSmall por defecto sino que sea TextAppearance nada más. Entonces tendremos los cuatro según la definición que arriba explicamos. Para esto tendremos que cambiar el estilo del los TextView y por lo tanto debemos usar el atributo android:textViewStyle:

[xml highlight=»13,38,39,40,41,42″ title=»Archivo: /res/values/themes.xml»]
<?xml version="1.0" encoding="utf-8"?>
<resources>

<style name="CustomTheme" parent="android:Theme.Holo.Light.DarkActionBar">

<!– Text styles –>
<item name="android:textAppearance">@style/CustomTheme.TextAppearance</item>
<item name="android:textAppearanceSmall">@style/CustomTheme.TextAppearance.Small</item>
<item name="android:textAppearanceMedium">@style/CustomTheme.TextAppearance.Medium</item>
<item name="android:textAppearanceLarge">@style/CustomTheme.TextAppearance.Large</item>

<!– Widget styles –>
<item name="android:textViewStyle">@style/CustomTheme.Widget.TextView</item>

</style>

<!– Text styles –>
<style name="CustomTheme.TextAppearance" parent="@android:style/TextAppearance">
<item name="android:textColor">@color/black</item>
<item name="android:textSize">16sp</item>
</style>

<style name="CustomTheme.TextAppearance.Small" parent="@android:style/TextAppearance.Small">
<item name="android:textColor">@color/green</item>
<item name="android:textSize">10sp</item>
</style>

<style name="CustomTheme.TextAppearance.Medium" parent="@android:style/TextAppearance.Medium">
<item name="android:textColor">@color/blue</item>
</style>

<style name="CustomTheme.TextAppearance.Large" parent="@android:style/TextAppearance.Large">
<item name="android:textColor">@color/red</item>
<item name="android:textStyle">bold</item>
</style>

<!– Widget styles –>
<style name="CustomTheme.Widget.TextView" parent="@android:style/Widget.TextView">
<item name="android:textAppearance">@style/CustomTheme.TextAppearance</item>
<item name="android:paddingTop">5dp</item>
<item name="android:paddingBottom">5dp</item>
</style>

[/xml]

A nuestro archivo themes.xml hemos agregado la línea 13 para decir que el estilo de los textviews sea delegado a un estilo de nuestro tema @style/CustomTheme.Widget.TextView y este estilo, definido en las líneas 38 a la 42, hereda de estilo por defecto de android para no hacerlo desde cero y cambiamos el TextAppearance por defecto al nuestro. También le agregamos unos padding arriba y abajo para mostrar como afectará a todos los TextViews.

Con esto tendremos la siguiente pantalla donde se ve que el padding afecto a los cuatro textviews pero sin embargo solo el normal tiene el texto en negro ya que en los otros tres fue definido el TextAppearance como atributo dentro del layout.

Pantalla de ejemplo con las nuevas modificaciones

Ahora cada vez que queramos escribir un texto simple usamos el Componente TextView de la paleta de Form Widget, cuando queramos un h1 usamos el Large, un título de segundo nivel (h2) el Medium y si queremos escribir texto pequeño usaremos el Small sin necesitar cambiar absolutamente nada en el layout.

Si quisiéramos que un TextView especial sea diferente a los estilos del tema definimos un estilo en el archivo styles.xml y lo aplicamos por medio del atributo style=”” en el layout.

Resumen Final

Con este ejemplo damos por terminado este artículo sobre temas y estilo en Android. El objetivo de este artículo fue netamente ver como se entender y modificar los temas ya que en la documentación oficial no tenemos mucha información y la única manera es ir analizando los temas ya existentes.

Lo más importante es recordar que si queremos analizar un tema tenemos tres archivos importantes, attr.xml, themes.xml y styles.xml. En attr.xml encontraremos los atributos para modificar los estilos, estos atributos se usan en themes.xml para delegar el estilo a uno creado por nosotros.

También les dejo el ejemplo completo en GitHub donde no solo pondré esto sino que también agregare algunos otros cambios a nuestro CustomTheme para los botones y los ListViews. A medida que vaya analizando nuevos atributos los iré actualizando.

Espero sus comentarios y si alguien puede aportar a nuestro código de ejemplo bienvenido.

Les dejo también un excelente artículo sobre le tema.


Descubre más desde Neurosimbiosis

Suscríbete y recibe las últimas entradas en tu correo electrónico.

5 comentarios en “Android – Styles & Themes”

  1. Buenas, ante todo darte las gracias por este magnífico tutorial.
    Me gustaría preguntarte cómo se podría customizar todos los Edittext que estén deshabilitados.
    A ver si puedes iluminarme, llevo un tiempo intentando hacerlo pero no lo consigo.

    Muchas gracias de nuevo por el tutorial, un saludo.

    1. Hola José. La verdad que no encontré la forma de hacerlo ya que para hacerlo global debería de existir al para poder modificarlo. Si lo puedes hacer con un estilo y aplicandolo a todos. Subí un ejemplo al igual que el editTextNumber en el github.

  2. Interesante tuto, problemas con este tema… la aparición de varias ‘carpetas’ values con sus respectivos archivos me confunde más! y en ese intento de querer arreglar algo se me descuadró los botones y algunos textview (no las etiquetas), se desplazaron hacia la derecha, y lo más raro que se aplicó a todos mis proyectos… no sé que modifiqué!. Ojalá puedas ayudarme. Gracias!

    1. Paul si cambiaste las carpetas originales te conviene descargarlas nuevamente y podrías compararlas con algún programa como winmerge o meld para ver que se modificó. Las modificaciones las tendrías que hacer dentro de tu proyecto.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *