Estandarizar botones entre versiones de Android

Una de las ventajas de Material es que hay cosas que se han simplificado. Por ejemplo los botones se pueden tintar del color que se quiera y ya no hay que hacer un drawable con 4 ó 5 9patch. Se le dice el color del texto y el del fondo y ya está. Por otro lado, aunque la mayoría de veces no hará falta volver al sistema antiguo, sigue estando disponible. Pero…

Hay un bug en Lollipop que afecta a como se renderizan los botones. El fondo no se colorea, en la siguiente imagen se puede ver mejor a qué me refiero.

En realidad no es un bug, no es que no se pueda definir, es una incongruencia en el nombre de los atributos para hacerlo.

El ejemplo de la imagen anterior, en código sería algo así:

<Button
   style="?android:attr/buttonStyleSmall"
   android:layout_width="0dp"
   android:layout_height="35dp"
   android:layout_weight="50"
   android:backgroundTint="@color/background"
   android:padding="0dp"
   android:text="@string/text"
   android:textColor="#FFF"
   android:textSize="10sp" />

No es tan sencillo, pero casi.

La solución que propongo sirve no sólo para que se vea igual en versiones 5.x y 6.x. He comprobado que funciona a partir de 4.x, la única diferencia es que en versiones tan antiguas (ICS tiene ya como 4 años) no renderízará las sombras realistas y en tiempo real que implementa Material.

Primero, agregar appcompat a gradle:

compile 'com.android.support:appcompat-v7:23.1.1'

Después habrá que preparar dos archivos de estilos diferentes, uno normal y otro -v21 (5.0). Como estos:

values/styles.xml

<resources>
    <style name="Button" parent="Widget.AppCompat.Button">
    </style>
    <style name="Button.Accent" parent="Button">
        <item name="colorButtonNormal">@color/colorAccent</item>
        <item name="android:textColor">@color/colorWhite</item>
    </style>
</resources>

values-v21/styles.xml

<resources>
    <style name="Button" parent="Widget.AppCompat.Button.Colored">
        <item name="android:layout_height">wrap_content</item>
    </style>
    <style name="Button.Accent" parent="Button">
        <item name="android:colorButtonNormal">@color/colorAccent</item>
        <item name="android:textColor">@color/colorWhite</item>
    </style>
</resources>

Y a la hora de usar el botón…

<Button
    android:theme="@style/Button.Accent"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/texto" />

Con eso ya estaría.

Sólo un detalle para cerrar el tema. Hay que extender de AppCompatActivity, no de Activity. En este último punto, cuando se usa Button en realidad se está usando AppCompatButton. Pero, como pone en la documentación de AppCompatButton, se usa automáticamente y sólo es necesario usarlo en caso de extar escribiendo una custom view.




Josep Viciana

Programador de 29 años con una década de experiencia como programador. interesado en el diseño, ilustración y nuevas tecnologías. Dedicado desde siempre a la programación Web y desde hace algunos años también a la móvil.

No hay comentarios


Puedes dejar el primero : )



Deja un comentario

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

Este sitio usa Akismet para reducir el spam. Conoce cómo se procesan los datos de tus comentarios.