Gracias por leer mi blog. En este post estaré explicándoles sobre los diferentes botones en Android. Si descargan el código de github y lo ejecutan en Android Studio, verán una pantalla como esta:
El SDK de Android nos proporciona tres tipos de botones: los clásicos de texto (Button), los que pueden contener una imagen (ImageButton), y los de tipo on/off (ToggleButton y Switch).
No voy a comentar detalladamente sobre ellos dado que son controles de sobra conocidos por todos, ni vamos a enumerar todas sus propiedades porque existen decenas. A modo de referencia, a medida que voy comentando iré poniendo enlaces a su página de la documentación oficial de Android para poder consultar todas sus propiedades en caso de necesidad.
Un control de tipo Button es el botón más básico que podemos utilizar y normalmente contiene un simple texto. En el ejemplo siguiente definimos un botón con el texto “Click” asignando su propiedad android:text. Además de esta propiedad podríamos utilizar muchas otras como el color de fondo (android:background), estilo de fuente (android:typeface), color de fuente (android:textcolor), tamaño de fuente (android:textSize), etc.
Este botón quedaría como se muestra en la siguiente imagen:
Un control de tipo ToggleButton es un tipo de botón que puede permanecer en dos posibles estados, pulsado o no_pulsado. En este caso, en vez de definir un sólo texto para el control definiremos dos, dependiendo de su estado. Así, podremos asignar las propiedades android:textOn y android:textoOff para definir ambos textos.
Veamos un ejemplo a continuación.
El botón se mostraría de alguna de las dos formas siguientes, dependiendo de su estado:
Un control Switch es muy similar al ToggleButton anterior, donde tan sólo cambia su aspecto visual, que en vez de mostrar un estado u otro sobre el mismo espacio, se muestra en forma de deslizador o interruptor. Su uso sería completamente análogo al ya comentado:
En un control de tipo ImageButton podremos definir una imagen a mostrar en vez de un texto, para lo que deberemos asignar la propiedad android:src. Normalmente asignaremos esta propiedad con el descriptor de algún recurso que hayamos incluido en las carpetas /res/drawable. Así, por ejemplo, en nuestro caso vamos a incluir una imagen llamada “ic_estrella.png” por lo que haremos referencia al recurso “@drawable/ic_estrella“. Adicionalmente, al tratarse de un control de tipo imagen también deberíamos acostumbrarnos a asignar la propiedad android:contentDescription con una descripción textual de la imagen, de forma que nuestra aplicación sea lo más accesible posible.
Cabe decir además, que aunque existe este tipo específico de botón para imágenes, también es posible añadir una imagen a un botón normal de tipo Button, a modo de elemento suplementario al texto (compound drawable).
Por ejemplo, si quisiéramos añadir un icono a la izquierda del texto de un botón utilizaríamos la propiedad android:drawableLeft indicando como valor el descriptor (ID) de la imagen que queremos mostrar, y si fuera necesario podríamos indicar también el espacio entre la imagen y el texto mediante la propiedad android:drawablePadding:
El botón mostrado en este caso sería similar a éste:
Eventos de un botón
Como podéis imaginar, aunque estos controles pueden lanzar muchos otros eventos, el más común de todos ellos y el que querremos capturar en la mayoría de las ocasiones es el eventoonClick, que se lanza cada vez que el usuario pulsa el botón. Para definir la lógica de este evento tendremos que implementarla definiendo un nuevo objeto View.OnClickListener() y asociándolo al botón mediante el método setOnClickListener(). La forma más habitual de hacer esto es la siguiente:
btnBotonSimple = (Button)findViewById(R.id.BtnBotonSimple);
btnBotonSimple.setOnClickListener(
new
View.OnClickListener() {
public
void
onClick(View arg0)
{
lblMensaje.setText(
"Botón Simple pulsado!"
);
}
});
En el caso de un botón de tipo ToggleButton o Switch suele ser de utilidad conocer en qué estado ha quedado el botón tras ser pulsado, para lo que podemos utilizar su métodoisChecked(). En el siguiente ejemplo se comprueba el estado del botón tras ser pulsado y se realizan acciones distintas según el resultado.
btnToggle = (ToggleButton)findViewById(R.id.BtnToggle);
btnToggle.setOnClickListener(
new
View.OnClickListener() {
public
void
onClick(View arg0)
{
if
(btnToggle.isChecked())
lblMensaje.setText(
"Botón Toggle: ON"
);
else
lblMensaje.setText(
"Botón Toggle: OFF"
);
}
});
Personalizar el aspecto un botón (y otros controles)
En las imágenes mostradas durante este apartado hemos visto el aspecto que presentan por defecto los diferentes tipos de botones disponibles. Pero, ¿y si quisiéramos personalizar su aspecto más allá de cambiar un poco el tipo o el color de la letra o el fondo?
Para cambiar la forma de un botón podríamos simplemente asignar una imagen a la propiedad android:background, pero esta solución no nos serviría de mucho porque siempre se mostraría la misma imagen incluso con el botón pulsado, dando poca sensación de elemento “clickable“.
La solución perfecta pasaría por tanto por definir diferentes imágenes de fondo dependiendo del estado del botón. Pues bien, Android nos da total libertad para hacer esto mediante el uso de selectores. Un selector se define mediante un fichero XML localizado en la carpeta /res/drawable, y en él se pueden establecer los diferentes valores de una propiedad determinada de un control dependiendo de su estado.
Por ejemplo, si quisiéramos dar un aspecto diferente a nuestro botón ToggleButton, para que sea de color azul y con esquinas redondeadas, podríamos diseñar las imágenes necesarias para los estados “pulsado” y “no pulsado” y crear un selector como el siguiente:
<
item
android:state_checked
=
"false"
android:drawable
=
"@drawable/toggle_off"
/>
<
item
android:state_checked
=
"true"
android:drawable
=
"@drawable/toggle_on"
/>
</
selector
>
En el código anterior vemos cómo se asigna a cada posible estado del botón una imagen (un elemento drawable) determinada. Así, por ejemplo, para el estado “pulsado” (state_checked=”true”) se asigna la imagen toggle_on.
Este selector lo guardamos por ejemplo en un fichero llamado toggle_style.xml y lo colocamos como un recurso más en nuestra carpeta de recursos /res/drawable. Hecho esto, tan sólo bastaría hacer referencia a este nuevo recurso que hemos creado en la propiedadandroid:background del botón:
<
ToggleButton
android:id
=
"@+id/BtnPersonalizado"
android:textOn
=
"@string/on"
android:textOff
=
"@string/off"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:background
=
"@drawable/toggle_style"
/>
En la siguiente imagen vemos el aspecto por defecto de nuestro ToggleButton personalizado con los cambios indicados:
Botones sin borde
Otra forma de personalizar los controles en Android es utilizando estilos. Los estilos merecen un capítulo a parte, pero comentaremos aquí algunos muy utilizados en las últimas versiones de Android, concretamente en el tema que nos ocupa de los botones.
En determinadas ocasiones, como por ejemplo cuando se utilizan botones dentro de otros elementos como listas o tablas, es interesante contar con todas la funcionalidad de un botón pero prescindiendo sus bordes de forma que adquiera un aspecto plano y se integre mejor con el diseño de la interfaz. Para ello, podemos utilizar el estilo borderlessButtonStyle como estilo del botón (propiedad style), de forma que éste se mostrará sin bordes pero conservará otros detalles como el cambio de apariencia al ser pulsado. Veamos cómo se definiría por ejemplo un ImageButton sin borde:
< ImageButton android:id = "@+id/BtnSinBorde" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:contentDescription = "@string/icono_ok" android:src = "@drawable/ic_estrella" style = "?android:borderlessButtonStyle" /> |
En la siguiente imagen vemos cómo quedaría este botón integrado dentro de un LinearLayout y alineado a la derecha:
El separador vertical que se muestra entre el texto y el botón se consigue utilizando las propiedades showDividers, divider, y dividerPadding del layout contenedor (para mayor claridad puede consultarse el código completo):
<
LinearLayout
android:id
=
"@+id/BarraBtnSinBorde"
android:layout_width
=
"match_parent"
android:layout_height
=
"wrap_content"
android:orientation
=
"horizontal"
android:showDividers
=
"middle"
android:divider
=
"?android:dividerVertical"
android:dividerPadding
=
"6dp"
>
Otro lugar muy habitual donde encontrar botones sin borde es en las llamadas barras de botones (button bar) que muestran muchas aplicaciones. Para definir una barra de botones, utilizaremos normalmente como contenedor un LinearLayout horizontal e incluiremos dentro de éste los botones (Button) necesarios, asignando a cada el elemento su estilo correspondiente, en este caso buttonBarStyle para el contenedor, y buttonBarButtonStyle para los botones. En nuestro ejemplo crearemos una barra con dos botones, Aceptar y Cancelar, que quedaría así:
<
LinearLayout
android:id
=
"@+id/BarraBotones"
android:layout_width
=
"match_parent"
android:layout_height
=
"wrap_content"
android:orientation
=
"horizontal"
android:layout_alignParentBottom
=
"true"
style
=
"?android:attr/buttonBarStyle"
>
<
Button
android:id
=
"@+id/BtnAceptar"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:layout_weight
=
"1"
android:text
=
"@string/Aceptar"
style
=
"?android:attr/buttonBarButtonStyle"
/>
<
Button
android:id
=
"@+id/BtnCancelar"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:layout_weight
=
"1"
android:text
=
"@string/Cancelar"
style
=
"?android:attr/buttonBarButtonStyle"
/>
</
LinearLayout
>
Visualmente el resultado sería el siguiente:
Botones flotantes (Floating Action Button / FAB)
Como contenido extra de este capítulo voy a hacer mención a un nuevo “tipo de botón” aparecido a raiz de la nueva filosofía de diseño Android llamada Material Design. Me refiero a los botones de acción flotantes que están incorporando muchas aplicaciones, sobre todo tras su actualización a Android 5 Lollipop.
Con la reciente publicación por parte de Google de la librería Design Support Library, añadir este tipo de botones a nuestras aplicaciones es algo de lo más sencillo, y además aseguramos su compatibilidad no sólo con Android 5.x sino también con versiones anteriores. En esta librería se incluye un nuevo componente llamado FloatingActionButton con la funcionalidad y aspecto deseados.
Lo primero que tendremos que hacer para utilizarlo será añadir la librería indicada a nuestro proyecto.
Una vez añadida la librería al proyecto como se describe en la nota anterior, podremos añadir un botón flotante a nuestra interfaz añadiendo un nuevo elemento a nuestro layout principal activity_main.xml de la siguiente forma:
<
android.support.design.widget.FloatingActionButton
android:id
=
"@+id/fab"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:src
=
"@drawable/ic_add"
app:fabSize
=
"normal"
app:borderWidth
=
"0dp"
/>
La propiedad más relevante, al igual que en el caso de un ImageButton, es android:src, con la que podemos asignar al control la imagen/icono a mostrar. En mi caso de ejemplo he utilizado un nuevo icono (ic_add) añadido al proyecto de la misma forma que explicamos al principio del artículo.
Vemos también la propiedad app:fabSize. Esta propiedad puede recibir los valores “normal” y “mini“, que determinan el tamaño del control dentro de los dos tamaños estandar definidos en las especificaciones de Material Design.
La última propiedad asignada, app:borderWidth=”0dp”, es necesaria temporalmente (en el momento de actualizar este artículo la versión actual de la librería es la 22.2) para evitar que el botón flotante aparezca sin sombra o con aspecto no estandar en algunas versiones de Android (por ejemplo APIs 16 o 22). Previsiblemente, este error lo corregirán en la siguiente versión de la librería, por lo que puede que en un futuro muy próximo ya no sea necesario asignar esta propiedad.
¿Y como seleccionamos el color del botón? Pues bien, si no indicamos nada, el botón flotante tomará por defecto el accent color si lo hemos definido en el tema de la aplicación o el color de selección actual. Si queremos utilizar otro color debemos hacerlo desde el código java de la aplicación, por ejemplo en el onCreate() de la actividad principal, llamando al método setBackgroundTintList() del control FloatingActionButton.
fabButton = (FloatingActionButton)findViewById(R.id.fab);
fabButton.setBackgroundTintList(
getResources().getColorStateList(R.color.fab_color));
Como parámetro debemos pasarle un objeto de tipo ColorStateList, que no es más que un selector de color (similar al selector que creamos antes para el ToggleButon personalizado) que crearemos en la carpeta /res/color por ejemplo con el nombre fab_color.xml y que recuperaremos en nuestro código mediante el método getResources().getColorStateList().
<
item
android:state_pressed
=
"true"
android:color
=
"#B90000"
/>
<
item
android:color
=
"#FF0000"
/>
</
selector
>
Como podemos ver, en el selector hemos definido el color normal del botón y su color cuando está pulsado.
Puedes bajar el código de https://github.com/gelopfalcon/Android/tree/master/curso-android-src-as-master/android-botones
Saludos.