En el artículo anterior del Curso de Programación en Android ya vimos los distintos tipos de layouts con los que contamos en Android para distribuir los controles de la interfaz por la pantalla del dispositivo. En los próximos artículos dedicados a Android vamos a hacer un repaso de los diferentes controles que pone a nuestra disposición la plataforma de desarrollo de este sistema operativo. Empezaremos con los controles más básicos y seguiremos posteriormente con algunos algo más elaborados.
En este primer post sobre el tema nos vamos a centrar en los diferentes tipos de botones y cómo podemos personalizarlos. El SDK de Android nos proporciona tres tipos de botones: el clásico (Button), el de tipo on/off (ToggleButton), y el que puede contener una imagen (ImageButton). En la imagen siguiente vemos el aspecto por defecto de estos tres controles.
No vamos a comentar mucho 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 los vayamos 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.
Control Button [API]
Un control de tipo Button es el botón más básico que podemos utilizar. En el ejemplo siguiente definimos un botón con el texto “Púlsame” 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.
<Button android:id="@+id/BtnBoton1" android:text="@string/pulsame" android:layout_width="wrap_content" android:layout_height="wrap_content" />
Control ToggleButton [API]
Un control de tipo ToggleButton es un tipo de botón que puede permanecer en dos posibles estados, pulsado/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.
<ToggleButton android:id="@+id/BtnBoton2" android:textOn="@string/on" android:textOff="@string/off" android:layout_width="wrap_content" android:layout_height="wrap_content" />
Control ImageButton [API]
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 la carpeta /res/drawable. Así, por ejemplo, en nuestro caso hemos incluido una imagen llamada “ok.png” por lo que haremos referencia al recurso “@drawable/ok“. 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.
<ImageButton android:id="@+id/BtnBoton3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/icono_ok" android:src="@drawable/ok" />
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. 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:
<Button android:id="@+id/BtnBoton5" android:text="@string/pulsame" android:drawableLeft="@drawable/ok" android:layout_width="wrap_content" android:layout_height="wrap_content" />
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 evento onClick, 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:
btnBoton1 = (Button)findViewById(R.id.BtnBoton1);
btnBoton1.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0)
{
lblMensaje.setText("Botón 1 pulsado!");
}
});
En el caso de un botón de tipo ToggleButton suele ser de utilidad conocer en qué estado ha quedado el botón tras ser pulsado, para lo que podemos utilizar su método isChecked(). En el siguiente ejemplo se comprueba el estado del botón tras ser pulsado y se realizan acciones distintas según el resultado.
btnBoton2 = (ToggleButton)findViewById(R.id.BtnBoton2);
btnBoton2.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0)
{
if(btnBoton2.isChecked())
lblMensaje.setText("Botón 2: ON");
else
lblMensaje.setText("Botón 2: OFF");
}
});
Personalizar el aspecto un botón [y otros controles]
En la imagen mostrada al principio del artículo vimos el aspecto que presentan por defecto los tres 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 plano a un botón ToggleButton, podríamos diseñar las imágenes necesarias para los estados “pulsado” (en el ejemplo toggle_on.png) y “no pulsado” (en el ejemplo toggle_off.png) y crear un selector como el siguiente:
<?xml version="1.0" encoding="UTF-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<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 propiedad android:background del botón:
<ToggleButton android:id="@+id/BtnBoton4" android:textOn="@string/on" android:textOff="@string/off" android:padding="10dip" 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 un ToggleButton (columna izquierda) y cómo ha quedado nuestro ToggleButton personalizado (columna derecha).
En las imágenes siguientes se muestra la aplicación de ejemplo desarrollada, donde se puede comprobar el aspecto de cada uno de los tipos de botón comentados para las versiones de Android 2.x y 4.x
Puedes consultar y/o descargar el código completo de los ejemplos desarrollados en este artículo accediendo a la pagina del curso en GitHub.
Curso de Programación Android en PDF
¿Te ha sido de utilidad el Curso de Programación Android? ¿Quieres colaborar de forma económica con el proyecto? Puedes contribuir con cualquier cantidad, unos céntimos, unos euros, cualquier aportación será bienvenida. Además, si tu aportación es superior a una pequeña cantidad simbólica recibirás como agradecimiento un documento con la última versión del curso disponible en formato PDF. Sea como sea, muchas gracias por colaborar!
Más información:





Muchisimas gracias!
Llevo varios días intentando aprender a desarrollar aplicaciones en Android y tus tutoriales me están ayudando muchísimo, tanto en la parte teórica como práctica.
Seguiré visitando tu blog para más tutoriales. Gracias por el curro!
Me alegro de que sea de utilidad, espero tener tiempo para escribir mucho más sobre el tema. Saludos.
Brutal, me encantan tus tutoriales, por fin una pagina decente cn tutoriales xDD
No sabes como te agradezco tu interés en enseñar a los demás.
La única web española que realmente tiene utilidad a la hora de aprender!
seguramente mucha gente ya se habrá dado cuenta pero te comento por si lo quieres cambiar que en los ejemplos de “Eventos de un botón” sería btnBoton1.setText(“Botón 1 pulsado!”) en lugar de lblMensaje.setText… y lo mismo para el segundo.
Un saludo!
Felicidades. Gran tutorial.
Estoy deseando exprimirlo al máximo y ponerme manos a la obra con un proyecto que tengo en mente.
jeje, aquí estoy, tema 2. Emmm, tengo un problemilla con el último botón. Veamos, en la carpeta drawable (las 3 que me genera Eclipse) he metido un XML plano, o sea, la opción de New>Other>XML>XML File, y he metido el código tuyo.
Lo que me está pasando es que no se ve el botón, el último ToogleButton del manual.
Siento el coñazo que te estoy dando. Ya me funciona, pero… me he bajado el típico png de ON OFF, y me pone el texto encima. O sea, quitando el android:textOn y el Off, sigue apareciendo el texto encima del botón.
A lo que me surge la pregunta. Se puede usar un ToggleButton sin que Android meta el texto de ON OFF??
Muy bueno el tutorial gracias. una duda nomas en caso de que yo quiera poner los buttons en una posicion especifica en px. como le ago? espero tu respuesta gracias
hola santy:
muy sencillo para lo del texto.
en android:textOn=”" no pones nada y no aparece nada
o android:textColor=”#00F1″ el primer cero despues de la almohadilla es el alfa o trasparencia que va de 0 a 9 continuando con “A” hasta “F” siendo “F” opaco y 0 transparente…. osea que no se ve
ESPERO HABER AYUDADO
Que onda bro gracias por tus tutoriales, muy buenos, tnego una duda en este tutorial, al copiar tu codigo en un nuevo proyecto en eclipse me marca un error en id
este:
final TextView lblMensaje = (TextView)findViewById(R.id.LblMensaje);
en R.id.Lbl queria ver si puedes ayudarme, se necsita deskargar algun pakete extra? saludos.
pd estas clases tngo
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.ToggleButton;
Gracias por este tutotial, bastante instuctivo.
Quiero hacerles una consulta, cuando utilizo la funcion setOnClickListener, android muestra un error indicando que la aplicacion se ha detenido inesperadamente. “Force Close”
Este es el codigo que utilizo:
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.interfaz);
texto = (EditText) findViewById(R.id.cajaTexto);
boton = (Button) findViewById(R.id.btnInvertir);
boton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
texto.setText(“Esto es un prueba”);
}
});
}
No entiendo porque no funciona este evento, espero me puedan ayudar a resolverlo.
Gracias.
Muchas gracias por estos tutoriales tan bueno, apenas me estoy iniciando en el tema de Android y los encuentro de maravilla, no solamente por las demostraciones, sino por el concepto de fondo con que son explicados.
Muchas gracias.
Muy buen post sobre Android
Una pregunta, el código de los eventos de los botones donde hay que colocarlo?? no me quedó claro.. intenté ponerlo en el Activiy así:
final Button boton1 = (Button)findViewById(R.id.button1);
pero la linea me da un Force Close. Gracias por sus respuestas :)
Hola Bernardo, al final del artículo tienes el código fuente completo del ejemplo, que puedes descargar y consultar en caso de cualquier duda sobre dónde definir cada cosa. De cualquier forma, decirte que ese código debe ir dentro del método onCreate() de la actividad. Saludos.
Buenas tardes a todos
yo estoy necesitando tomar unas fotos por medio de una aplicación de Android (que ya se hizo) pero quiero que me guarde pro carpetas que yo seleccione pero no he podido como y no encuentro como, no se si me puedan ayudar, si conocen algún foro donde este esto. les agradezco mucho la colaboración
que estén muy bien
Tengo un pequeño problema, al ingresar las imagenes en las carpetas res/drawable no las ingresa automaticamente a la clase R, lo cual me genera un error en el tag android:src” en el xml a la hora de poner la imagen en el ImageButton, el error dice que no existe el recurso :/
Gracias por compartir, estoy iniciandome en android y no sabía como interactuar con botones, esta información me iluminó bastante.
Saludos.
Muchas Gracias por este tutorial realmente. resulta de mucho ayuda.