Creación de escuchadores de eventos

Un escuchador de eventos (event listener) es un mecanismo que nos permite reaccionar de forma asíncrona ante ciertas circunstancias que ocurren en clases diferentes a la nuestra. Es un sistema de comunicación muy habitual en Java; seguro que lo habrás utilizado para detectar si un botón ha sido pulsado, para saber que cambia la localización del dispositivo o el valor de un sensor. Para usar un escuchador de eventos hemos de seguir tres pasos:

  • Implementar la interfaz del escuchador (p. ej. OnClickListener).
  • Registrar el escuchador en el objeto que genera el evento indicándole el objeto que los recogerá (p. ej. boton.setOnClickListener(this)).
  • Implementar los métodos callback correspondientes (ej. @Override public void onClick(View v) {...}).

Puede serte útil repasar estos conceptos en el siguiente vídeo:


 Vídeo[Tutorial]: Escuchadores de eventos en Android

Cuando creas una vista nueva es muy posible que quieras avisar a los objetos que están usando esta vista de que ocurren ciertos eventos. En estos casos puede ser interesante crear un escuchador de eventos. Para esto, sigue los siguientes tres pasos:

  • Crea una nueva interfaz donde indiques la lista de métodos callback correspondientes a los diferentes eventos que podías generar. El nombre de esta interfaz ha de ser algo parecido a OnMiVistaListener. Donde has de reemplazar MiVista por el nombre de la vista.
  • Crea el método setOnMiVistaListener(OnMiVistaListener escuchador) para que un objeto que haya implementado tu interfaz pueda registrarse para recibir eventos. En este método solo tienes que guardar la referencia a escuchador.
  • Cada vez que quieras enviar un evento a tu escuchador llama a uno de los métodos callback que tu escuchador implementa.

Resulta mucho más sencillo de comprender cuando se ve en un ejemplo. Te recomendamos que hagas el siguiente ejercicio:

 

Ejercicio paso a paso: Añadir un escuchador de evento a la vista.

 

1.    Pulsa con el botón derecho sobre el proyecto VistaConectar y selecciona New/Interface. Introduce como nombre OnConectarListener. El código se muestra a continuación:

package com.example.vistaconectar;

public interface OnConectarListener {

   void onConectar(String ip, int puerto);

   void onConectado(String ip, int puerto);

   void onDesconectado();

   void onError(String mensage);

}

Este escuchador de evento podrá generar cuatro eventos diferentes: el usuario ha pulsado el botón para conectarse, nos acabamos de conectar, nos hemos desconectado y se ha producido un error. Estos métodos se conocen como métodos callback.

2.     Añade la siguiente variable al principio de la clase VistaConectar:

private OnConectarListener escuchador;

3.     Añade el siguiente método a la clase VistaConectar:

public void setOnConectarListener(OnConectarListener escuchador) {

   this.escuchador = escuchador;

}

Estos dos elementos permitirán registrar el escuchador al que tenemos que mandar los eventos.

4.     Añade las siguientes líneas al final del constructor de la clase VistaConectar:

conectar.setOnClickListener(new OnClickListener() {

   @Override

   public void onClick(View v) {

      intnPuerto;

      try{

         nPuerto = Integer.parseInt(puerto.getText().toString());

      } catch (Exception e) {

         if(escuchador != null) {

            escuchador.onError("El puerto ha de ser un valor numérico");

         }

         estado.setText("ERROR");

         return;

      }

      if(nPuerto < 0 || nPuerto > 65535) {

         if(escuchador != null) {

            escuchador.onError("El puerto ha de un entero menor de 65536");

         }

         estado.setText("ERROR");

      } else {

         if(escuchador != null) {

            escuchador.onConectar(ip.getText().toString(), nPuerto);

         }

         estado.setText("Conectando ...");

      }

      // Conectar el socket ...

   }

});

 

Con este código estamos creando un método callback, onClick de un objeto anónimo de tipo OnClickListener y hemos registrado esta interfaz al botón conectar. De esta forma cuando se produzca el evento de pulsación se llamará a este método.

Comenzamos pasando el puerto de String a entero. Si el usuario no ha puesto un valor correcto, llamamos al método callback onError del objeto que se ha registrado como escuchador. No siempre habrá un escuchador registrado, en este caso el escuchador será null. Además, en el TextView estadomostramos que se ha producido un error.

También verificamos el rango de puertos válidos y actuamos de forma similar a la anterior. En caso de no encontrar ningún error llamamos al método callback onConectar pasándole la dirección del socket.

5.     Vamos a usar este escuchador de eventos desde MainAntivity.java; pero esta vez en lugar de crear un objeto anónimo la propia clase implementará la interfaz. Modifica la declaración de la clase para que quede:

public class MainActivity extends Activity implements OnConectarListener {
 
6.    Añade las siguientes líneas al método onCreate:

VistaConectar conectar = (VistaConectar) findViewById(R.id.vistaConectar);conectar.setOnConectarListener(this);

Con esto estamos indicando a vistaConectar que nosotros seremos su escuchador de eventos.

7.     En la declaración de la clase MainActivity aparecerá subrayada en rojo. Si pones el ratón encima te indicará que no se han implementado los métodos de la interfaz. Selecciona la opción Add unimplemented methods para que se incluyan automáticamente. Es imprescindible implementar todos los métodos de una interfaz.

8.     Añade a estos métodos el código que se muestra a continuación:

   @Override publicvoidonConectar(String ip, intpuerto) {

      Toast.makeText(getApplicationContext(), "Conectando "+ ip + ":"+
                                                                          puerto, Toast.LENGTH_SHORT).show();

   }

   @Override publicvoidonConectado(String ip, intpuerto) {

      // TODOAuto-generated method stub

   }

   @OverridepublicvoidonDesconectado() {

      // TODOAuto-generated method stub

   }

   @Override publicvoidonError(String mensage) {

      Toast.makeText(getApplicationContext(), mensage,

                                                                                 Toast.LENGTH_SHORT).show();

   }

 

9.     Ejecuta el proyecto y verifica que funciona correctamente.

10.     Observa el último comentario // Conectar el socket ... . Como se indica en esta vista faltaría mucho trabajo por realizar. De hecho hay eventos que nunca son generados. Aquí podrías tomar dos decisiones de diseño diferentes: que la vista se encargue solo de recoger la dirección o que también se encargue de conectar y enviar información a socket. Si quieres información sobre sockets puedes consultar el capítulo 10 de El gran libro de Android.

 
 
Preguntas de repaso: Escuchador de eventos