Button. ToggleButton. Control de eventos II

De MediaWiki
Saltar a: navegación, buscar

Introdución

  • Os botóns (button) permiten ao usuario indicar á aplicación que realice unha acción.
  • Os botóns poden ter Texto, unha imaxe ou as dúas cousas:
  • Ben o texto ou a imaxe comunican claramente ao usuario cal é a función do botón.

00 button-types.png


  • Estes controles son subclases de:
    • Button de TextView
    • ToogleButton de CompoundButton
    • ImageButton de ImageView (que se verá proximamente)

00 Part of Android View Hierarchy.png



  • Observar como se definen os tres tipos de botóns anteriores:
  • Botón con texto:
  1. <Button
  2.    android:layout_width="wrap_content"
  3.    android:layout_height="wrap_content"
  4.    android:text="@string/button_text"
  5.    ... />


  • Botón con imaxe
  1. <ImageButton
  2.    android:layout_width="wrap_content"
  3.    android:layout_height="wrap_content"
  4.    android:src="@drawable/button_icon"
  5.    ... />


  • Botón con texto e imaxe. A propiedade android:drawableLeft indica onde se sitúa a imaxe.
  1. <Button
  2.    android:layout_width="wrap_content"
  3.    android:layout_height="wrap_content"
  4.    android:text="@string/button_text"
  5.    android:drawableLeft="@drawable/button_icon"
  6.    ... />


  • Os botóns teñen unha propiedade android:onClick="oMeuMetodo" que nos permite chamar ao método indicado cando o pulsamos.
    • Ese método hai que declaralo en Java como public void oMeuMetodo (View v) { ... }
    • Recibe o obxecto View de quen o chamou.


  • Os botóns (Button) son subclases de TextView.


Botóns de 2 estados: ToggleButton/Switch

  • Existe outro tipo de botón de 2 estados (ON/OFF).
  • Un máis básico: <ToggleButton>

00 togglebutton.png

  • E outro máis avanzado (versión Android 4.0 ou superior): <Switch/>

00 switch.png

    • Permiten cambiar o seu estado desprazando co dun estado a outro. O funcionamento é semellante ao control ToogleButton.


  • Un obxecto ToogleButton/Switch herda da clase CompoundButton, quen, á súa vez, herda da clase Button.
  • Por tanto funcionan da mesma maneira, pero ademais o este tipo de botóns:
    • ten 2 estados (True/False), que pode podemos comprobar co método isChecked ()
    • Para cada estado podemos amosar un texto distinto no botón: android:TextOn e android:TextOFF.


Casos prácticos

Se non o temos creado antes, crea un paquete de nome UI como un subpaquete do teu paquete principal.
Dentro do paquete UI, crearemos un novo paquete de nome: Buttons.



  • Dentro do paquete Buttons crear unha nova 'Empty Activity' de nome: UD02_01_Buttons de tipo Launcher e sen compatibilidade.
Modifica o arquivo AndroidManifiest.xml e engade unha label á activity como xa vimos na creación do proxecto base.


  • Imos crear 3 botóns:
    • 1 Botón con texto
    • 1 ToogleButton
    • 1 botón con imaxe




Creación do layout

  • O layout XML ten 3 botóns e 1 TextView:
  • Observar como hai un layout dentro doutro: un dispón os elementos en vertical e o outro en horizontal.
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     xmlns:tools="http://schemas.android.com/tools"
  4.     android:layout_width="match_parent"
  5.     android:layout_height="match_parent"
  6.     android:orientation="vertical" >
  7.  
  8.     <LinearLayout
  9.         android:layout_width="match_parent"
  10.         android:layout_height="wrap_content"
  11.         android:orientation="horizontal" >
  12.  
  13.         <Button
  14.             android:id="@+id/btnBoton_UD02_01_buttons"
  15.             android:layout_width="150sp"
  16.             android:layout_height="wrap_content"
  17.             android:text="Preme aquí" >
  18.         </Button>
  19.  
  20.         <ToggleButton
  21.             android:id="@+id/tbtnDosEstados_UD02_01_buttons"
  22.             android:layout_width="100dp"
  23.             android:layout_height="match_parent"
  24.             android:textOff="Apagado"
  25.             android:textOn="Aceso" >
  26.         </ToggleButton>
  27.  
  28.         <ImageButton
  29.             android:id="@+id/ibtnImagen_UD02_01_buttons"
  30.             android:layout_width="55sp"
  31.             android:layout_height="50sp"
  32.             android:scaleType="fitXY"
  33.             android:src="@drawable/ic_launcher_foreground" >
  34.         </ImageButton>
  35.     </LinearLayout>
  36.  
  37.     <TextView
  38.         android:id="@+id/txtTv_accion_UD02_01_Buttons"
  39.         android:layout_width="wrap_content"
  40.         android:layout_height="wrap_content"
  41.         android:text="@string/texto_tv_string" />
  42.  
  43. </LinearLayout>


  • Se cargamos este layout e non realizamos ningunha codificación en Java, non vai pasar nada cos botóns:
Isto é debido a que non temos codificado ningunha acción para cando se preme en cada un deles.



Eventos

  • Para asociar un evento a un botón, podemos facelo:
  • Asociando, como vimos na xestión de eventos, unha interface a cada botón e rexistrando o evento que queiramos controlar (nesta caso dun click).
  • No caso dos botón, podemos facelo no layout da activity.


  • Nesta ocasión imos ver dun xeito sinxelo como capturar os eventos dos botóns.
  • Un evento é algo que acontece nun control e que nos interesa capturar no sistema para desencadear (ou non) unha serie de accións.
  • Xa vimos no caso anterior (EditText) que podíamos controlar eventos que acontecen nos controis.



Control de eventos dende o layout

  • É a forma máis sinxela de desencadear unha acción.
  • Imos facelo de dúas formas:
    • Creando un método para cada Botón.
    • Creando un único método para tódolos botóns. Hai que controlar que botón foi o que se premeu.

Crear un método para cada botón

  • Observar a propiedade: android:onClick nos controis dos botóns.
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     xmlns:tools="http://schemas.android.com/tools"
  4.     android:layout_width="match_parent"
  5.     android:layout_height="match_parent"
  6.     android:orientation="vertical" >
  7.  
  8.     <LinearLayout
  9.         android:layout_width="match_parent"
  10.         android:layout_height="wrap_content"
  11.         android:orientation="horizontal" >
  12.  
  13.         <Button
  14.             android:id="@+id/btnBoton_UD02_01_buttons"
  15.             android:layout_width="150sp"
  16.             android:layout_height="wrap_content"
  17.             android:onClick="onBotonClick"
  18.             android:text="Preme aquí" >
  19.         </Button>
  20.  
  21.         <ToggleButton
  22.             android:id="@+id/tbtnDosEstados_UD02_01_buttons"
  23.             android:layout_width="100dp"
  24.             android:layout_height="match_parent"
  25.             android:onClick="onBoton2EstadosClick"
  26.             android:textOff="Apagado"
  27.             android:textOn="Aceso" >
  28.         </ToggleButton>
  29.  
  30.         <ImageButton
  31.             android:id="@+id/ibtnImagen_UD02_01_buttons"
  32.             android:layout_width="55sp"
  33.             android:layout_height="50sp"
  34.             android:onClick="onBotonImaxeClick"
  35.             android:scaleType="fitXY"
  36.             android:src="@drawable/ic_launcher_foreground" >
  37.         </ImageButton>
  38.     </LinearLayout>
  39.  
  40.     <TextView
  41.         android:id="@+id/txtTv_accion_UD02_01_Buttons"
  42.         android:layout_width="wrap_content"
  43.         android:layout_height="wrap_content"
  44.         android:text="@string/texto_tv_string2" />
  45.  
  46. </LinearLayout>
  • Para cada botón defínese un método que xestione o evento onClick.
  • Deixamos para o participante no curso a definición no ficheiro /res/values/strings.xml da constante "@string/texto_tv_string2" do último TextView. (podedes poñer calquera texto de exemplo).


  • Agora só queda definir os métodos en Java.
  1. package es.cursoandroid.cifprodolfoucha.aprendiendo.UI.Buttons;
  2.  
  3. import android.app.Activity;
  4. import android.os.Bundle;
  5. import android.view.View;
  6. import android.widget.Button;
  7. import android.widget.ImageButton;
  8. import android.widget.TextView;
  9. import android.widget.ToggleButton;
  10.  
  11. import es.cursoandroid.cifprodolfoucha.aprendiendo.R;
  12.  
  13. public class UD02_01_Buttons extends Activity {
  14.  
  15.     private Button btnBoton;
  16.     private ToggleButton tbtnBoton2Estados;
  17.     private ImageButton ibtnBotonImaxe;
  18.     private TextView tvAccions;
  19.  
  20.     @Override
  21.     protected void onCreate(Bundle savedInstanceState) {
  22.         super.onCreate(savedInstanceState);
  23.         setContentView(R.layout.activity_ud02_01__buttons);
  24.  
  25.         btnBoton = (Button) findViewById(R.id.btnBoton_UD02_01_buttons);
  26.         tbtnBoton2Estados = (ToggleButton) findViewById(R.id.tbtnDosEstados_UD02_01_buttons);
  27.         ibtnBotonImaxe = (ImageButton) findViewById(R.id.ibtnImagen_UD02_01_buttons);
  28.         tvAccions = (TextView) findViewById(R.id.txtTv_accion_UD02_01_Buttons);
  29.  
  30.     }
  31.  
  32.     public void onBotonClick(View v) {
  33.         tvAccions.setText("Premeches o primeiro botón\n");
  34.         tvAccions.append("O texto do botón é: " + btnBoton.getText());
  35.     }
  36.  
  37.     public void onBoton2EstadosClick(View v) {
  38.         tvAccions.setText("Premeches o segundo botón\n");
  39.         if (tbtnBoton2Estados.isChecked())
  40.             tvAccions.append("O estado é: " + tbtnBoton2Estados.getTextOn());
  41.         else
  42.             tvAccions.append("O estado é: " + tbtnBoton2Estados.getTextOff());
  43.     }
  44.  
  45.     public void onBotonImaxeClick(View v) {
  46.         tvAccions.setText("Premeches o terceiro botón\n");
  47.         tvAccions.append("O ancho é: " + ibtnBotonImaxe.getWidth());
  48.     }
  49.  
  50.  
  51. }
  • Liñas 15-18: declaración de atributos.
  • Liñas 25-28: asignación de valores aos atributos mediante a clase R.
  • Liñas 32-35: Define o método asociado ao evento android:onClick do primeiro botón. "\n" introduce un salto de liña.
  • Liñas 37-43: Define o método asociado ao evento android:onClick do botón ToggleButton. Comprobamos se está activado o non.
  • Liñas 45-48: Define o método asociado ao evento android:onClick do botón con Imaxe.
  • Lanzar a aplicación e comprobar que sucede ao premer os botóns.



Crear un único método para tódolos botóns

  • Hai que modificar o XML para que as propiedades android:onClick de tódolos botóns chamen ao mesmo método.
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     xmlns:tools="http://schemas.android.com/tools"
  4.     android:layout_width="match_parent"
  5.     android:layout_height="match_parent"
  6.     android:orientation="vertical" >
  7.  
  8.     <LinearLayout
  9.         android:layout_width="match_parent"
  10.         android:layout_height="wrap_content"
  11.         android:orientation="horizontal" >
  12.  
  13.         <Button
  14.             android:id="@+id/btnBoton_UD02_01_buttons"
  15.             android:layout_width="150sp"
  16.             android:layout_height="wrap_content"
  17.             android:onClick="onBotonClick"
  18.             android:text="Preme aquí" >
  19.         </Button>
  20.  
  21.         <ToggleButton
  22.             android:id="@+id/tbtnDosEstados_UD02_01_buttons"
  23.             android:layout_width="100dp"
  24.             android:layout_height="match_parent"
  25.             android:onClick="onBotonClick"
  26.             android:textOff="Apagado"
  27.             android:textOn="Aceso" >
  28.         </ToggleButton>
  29.  
  30.         <ImageButton
  31.             android:id="@+id/ibtnImagen_UD02_01_buttons"
  32.             android:layout_width="55sp"
  33.             android:layout_height="50sp"
  34.             android:onClick="onBotonClick"
  35.             android:scaleType="fitXY"
  36.             android:src="@drawable/ic_launcher_foreground" >
  37.         </ImageButton>
  38.     </LinearLayout>
  39.  
  40.     <TextView
  41.         android:id="@+id/txtTv_accion_UD02_01_Buttons"
  42.         android:layout_width="wrap_content"
  43.         android:layout_height="wrap_content"
  44.         android:text="@string/texto_tv_string" />
  45.  
  46. </LinearLayout>



  • A definición do método:
  1. package es.cursoandroid.cifprodolfoucha.aprendiendo.UI.Buttons;
  2.  
  3. import android.app.Activity;
  4. import android.os.Bundle;
  5. import android.view.View;
  6. import android.widget.Button;
  7. import android.widget.ImageButton;
  8. import android.widget.TextView;
  9. import android.widget.ToggleButton;
  10.  
  11. import es.cursoandroid.cifprodolfoucha.aprendiendo.R;
  12.  
  13. public class UD02_01_Buttons extends Activity {
  14.  
  15.     /*
  16.     private Button btnBoton;
  17.     private ToggleButton tbtnBoton2Estados;
  18.     private ImageButton ibtnBotonImaxe;
  19.     */
  20.     private TextView tvAccions;
  21.  
  22.     public void onBotonClick(View vista) {
  23.  
  24.         switch (vista.getId()) {
  25.             case R.id.btnBoton_UD02_01_buttons:
  26.                 tvAccions.setText("Premeches o primeiro botón\n");
  27.                 tvAccions.append("O texto do botón é: "
  28.                         + ((Button) vista).getText());
  29.                 break;
  30.  
  31.             case R.id.tbtnDosEstados_UD02_01_buttons:
  32.                 tvAccions.setText("Premeches o segundo botón\n");
  33.                 if (((ToggleButton) vista).isChecked())
  34.                     tvAccions.append("O estado é: "
  35.                             + ((ToggleButton) vista).getTextOn());
  36.                 else
  37.                     tvAccions.append("O estado é: "
  38.                             + ((ToggleButton) vista).getTextOff());
  39.                 break;
  40.  
  41.             case R.id.ibtnImagen_UD02_01_buttons:
  42.                 tvAccions.setText("Premeches o terceiro botón\n");
  43.                 tvAccions.append("O ancho é: " + ((ImageButton) vista).getWidth());
  44.         }
  45.     }
  46.  
  47.  
  48.     @Override
  49.     protected void onCreate(Bundle savedInstanceState) {
  50.         super.onCreate(savedInstanceState);
  51.         setContentView(R.layout.activity_ud02_01__buttons);
  52.  
  53.         tvAccions = (TextView) findViewById(R.id.txtTv_accion_UD02_01_Buttons);
  54.         /*
  55.         btnBoton = (Button) findViewById(R.id.btnBoton_UD02_01_buttons);
  56.         tbtnBoton2Estados = (ToggleButton) findViewById(R.id.tbtnDosEstados_UD02_01_buttons);
  57.         ibtnBotonImaxe = (ImageButton) findViewById(R.id.ibtnImagen_UD02_01_buttons);
  58.         */
  59.  
  60.     }
  61.  
  62.     /*
  63.     public void onBotonClick(View v) {
  64.         tvAccions.setText("Premeches o primeiro botón\n");
  65.         tvAccions.append("O texto do botón é: " + btnBoton.getText());
  66.     }
  67.  
  68.     public void onBoton2EstadosClick(View v) {
  69.         tvAccions.setText("Premeches o segundo botón\n");
  70.         if (tbtnBoton2Estados.isChecked())
  71.             tvAccions.append("O estado é: " + tbtnBoton2Estados.getTextOn());
  72.         else
  73.             tvAccions.append("O estado é: " + tbtnBoton2Estados.getTextOff());
  74.     }
  75.  
  76.     public void onBotonImaxeClick(View v) {
  77.         tvAccions.setText("Premeches o terceiro botón\n");
  78.         tvAccions.append("O ancho é: " + ibtnBotonImaxe.getWidth());
  79.     }
  80.  
  81.     */
  82. }
  • Liñas 22-45:
    • Na chamada ao método recibimos como parámetro unha View (vista) que apunta ao obxecto que o chamou.
    • Collendo o ID da vista, podemos saber que botón foi o que iniciou o evento.
    • Con switch - case, en función do botón que lanzou o evento executamos o código correspondente.
  • Liñas 33, 35 e 38:
    • Observar como se fai casting do obxecto recibido. Recíbese un obxecto de tipo View (vista) e precisamos convertelo á ToogleButton para acceder aos seus métodos específicos.



Control de eventos usando un listener. Clase anónima

Queda como tarefa para o alumno, implementar a xestión de eventos deste exercicio facendo uso das interfaces (lembrar quitalo do layout).






-- Ángel D. Fernández González e Carlos Carrión Álvarez -- (2015).