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.

Comentarios (0)

No hay comentarios. Sé el primero en comentar.

Deja una respuesta

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. Aprende cómo se procesan los datos de tus comentarios.