Xestion de eventos III. onLongClick

De Manuais Informática - IES San Clemente.
Ir a la navegación Ir a la búsqueda

Introdución

  • En Android hai moitas formas de interceptar eventos do usuario.
  • A clase View proporciona varias formas de xestionar eventos.
  • Por exemplo cando un usuario toca un botón e chamado o método callback onTouchEvent() dese obxecto.
  • Pero para interceptar ese evento debemos estender a clase e implementar o método.
  • Pero non sería práctico para poder manexar o evento crear unha (sub)clase para cada obxecto Vista.
  • Por iso a Clase Vista conten unha colección de interfaces anidadas.
  • Estas interfaces chámanse Event Listeners (Escoitadores de eventos) e están listas para capturar a iteración do usuario coa UI.
  • A continuación imos ver algunhas formas de capturar eventos:



Caso práctico

  • Comezamos creando o proxecto: U3_02_Eventos
  • Comezaremos capturado o evento Click e logo ao final veremos outros eventos.
  • A aplicación coa que se traballará é a seguinte:

Android 2013 U3 02 Eventos 01.jpg


XML do Layout

  • A liña 11 marca unha das formas máis sinxelas de capturar o evento Click sobre un compoñente.
 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical">
 6 
 7     <Button
 8         android:layout_width="match_parent"
 9         android:layout_height="wrap_content"
10         android:text="Botón1: onClick Layout"
11         android:onClick="onBotonClick"
12          />
13     
14     <Button 
15         android:id="@+id/boton2"
16         android:layout_width="match_parent"
17         android:layout_height="wrap_content"
18         android:text="Botón2: Listener"
19         />
20 	
21 	<Button 
22         android:id="@+id/boton3"
23         android:layout_width="match_parent"
24         android:layout_height="wrap_content"
25         android:text="Botón3: Clase"
26         />
27 	
28     <Button 
29         android:id="@+id/boton4"
30         android:layout_width="match_parent"
31         android:layout_height="wrap_content"
32         android:text="Botón4: Tamén de clase"
33         />
34 
35     <Button 
36         android:id="@+id/boton5"
37         android:layout_width="match_parent"
38         android:layout_height="wrap_content"
39         android:text="Botón5: Obxecto"
40         />
41     
42     <Button 
43         android:id="@+id/boton6"
44         android:layout_width="match_parent"
45         android:layout_height="wrap_content"
46         android:text="Botón6: Outro Obxecto"
47         />
48 </LinearLayout>


O Código Java

  • A continuación preséntase o código Java, pero este vai ser debullado nos seguintes apartados.


 1 package com.example.u3_02_eventos;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.view.Menu;
 6 import android.view.View;
 7 import android.view.View.OnClickListener;
 8 import android.widget.Button;
 9 import android.widget.Toast;
10 
11 public class U3_02_Eventos extends Activity {
12 
13 	@Override
14 	protected void onCreate(Bundle savedInstanceState) {
15 		super.onCreate(savedInstanceState);
16 		setContentView(R.layout.activity_u3_02__eventos);
17 
18 		Button boton2 = (Button) findViewById(R.id.boton2);
19 		boton2.setOnClickListener(new OnClickListener() {
20 
21 			@Override
22 			public void onClick(View v) {
23 				Toast.makeText(getApplicationContext(), "Premeches o Botón2", Toast.LENGTH_SHORT).show();
24 			}
25 		});
26 
27 		Button boton3 = (Button) findViewById(R.id.boton3);
28 		boton3.setOnClickListener(new XestionEventos());
29 
30 		Button boton4 = (Button) findViewById(R.id.boton4);
31 		boton4.setOnClickListener(new XestionEventos());
32 
33 		Button boton5 = (Button) findViewById(R.id.boton5);
34 		boton5.setOnClickListener(_OnClickListener);
35 
36 		Button boton6 = (Button) findViewById(R.id.boton6);
37 		boton6.setOnClickListener(_OnClickListener);
38 
39 	}
40 
41 	private OnClickListener _OnClickListener = new OnClickListener() {
42 
43 		@Override
44 		public void onClick(View v) {
45 			Button btn = (Button) v;
46 			Toast.makeText(v.getContext(), "Premeches" + btn.getText(), Toast.LENGTH_SHORT).show();
47 		}
48 	};
49 
50 	public void onBotonClick(View v) {
51 		Toast.makeText(this, "Premeches o Botón1", Toast.LENGTH_SHORT).show();
52 	}
53 
54 	@Override
55 	public boolean onCreateOptionsMenu(Menu menu) {
56 		// Inflate the menu; this adds items to the action bar if it is present.
57 		getMenuInflater().inflate(R.menu.u3_02__eventos, menu);
58 		return true;
59 	}
60 
61 }

Propiedade android:onClick

  • Como xa se view é unha propiedade XML que teñen varios compoñentes (vistas).
  • Hai que definir un método:
    • Que sexa public
    • Que non devolva nada: void
    • Que teña un parámetro da clase View, que será quen provoque o evento.
  • No exemplo anterior son as liñas 50-52:
1 	public void onBotonClick(View v) {
2 		Toast.makeText(this, "Premeches o Botón1", Toast.LENGTH_SHORT).show();
3 	}

Listener

  • Un Event Listener es una interface da clase Vista (View) que contén un único método de tipo callback que hai que implmentar
  • Android invoca estes métodos cando a Vista detecta que o usuario está provocando un tipo concreto de interacción con este elemento da interface de usuario.

Existen os seguintes métodos callback:

    • onClick(): de View.OnClickListener. Este método invócase cando o usuario toca un elemento cun dedo (modo contacto), fai click coa bola de navegación (TrackBall) do dispositivo ou preme a tecla "Enter" estando nun compoeñente.
    • onLongClick(): de View.OnLongClickListener. Este método chámase cando o usuario toca e mantén o dedo sobre un elemento (modo de contacto), fai click sen soltar coa bola de navegación (TrackBall) ou preme a tecla "Enter" perante un segundo estando nun elemento.
    • onFocusChange(): de View.OnFocusChangeListener. Invócase cando o usuario move o cursor cara unha Vista ou se alonxa desta utilizando a bola de navegación ou usando as teclas de navegación.

onKey(): de View.OnKeyListener. Chámase cando o usuario se centra nun elemento e presiona ou libera una tecla do dispositivo.

    • ...
  • onLongClick() verase nun exemplo posterior.


  • Estes métodos son os únicos que se van implementar nas súas respectivas interfaces.
  • Estas interfaces teñen o formato: on...Listener()
  • Unha vez que temos implementada a interface témoslla que pasar como parámetro á vista (view) correspondente a través de vista.set...Listener().

A través dunha clase anónima

  • Exemplo: Liñas 18-25 do código
1                 Button boton2 = (Button) findViewById(R.id.boton2);
2 		boton2.setOnClickListener(new OnClickListener() {
3 
4 			@Override
5 			public void onClick(View v) {
6 				Toast.makeText(getApplicationContext(), "Premeches o Botón2", Toast.LENGTH_SHORT).show();
7 			}
8 		});


Implementar a interface a través dunha clase

  • Creamos unha nova clase que implemente onClickListener

Android 2013 U3 02 Eventos 02.jpg

  • Código Java da clase: XestionEventos
 1 package com.example.u3_02_eventos;
 2 
 3 import android.view.View;
 4 import android.view.View.OnClickListener;
 5 import android.widget.Button;
 6 import android.widget.Toast;
 7 
 8 public class XestionEventos implements OnClickListener {
 9 
10 	@Override
11 	public void onClick(View v) {
12 		// TODO Auto-generated method stub
13 		
14 		Button btn = (Button) v;
15 		Toast.makeText(v.getContext(), "Premeches "+btn.getText(), Toast.LENGTH_SHORT).show();
16 	}
17 }


  • Observar nas Liñas 28 e 31 (do código principal) como se crea unha nova clase XestionEventos para cada botón.
  • Esa clase é a que vai implementar o método onClick(), como se ve enriba.
1 		Button boton3 = (Button) findViewById(R.id.boton3);
2 		boton3.setOnClickListener(new XestionEventos());
3 
4 		Button boton4 = (Button) findViewById(R.id.boton4);
5 		boton4.setOnClickListener(new XestionEventos());
  • Pero esta forma é un engorro, pois hai que estar creando clases.


Crear un obxecto que implemente a interface

  • Para rematar imos crear un obxecto que implemente a interface e que poida ser pasado como parámetro as vistas que desexemos cada vez que se fai click nelas.
  • _OnClickLister é un obxecto de tipo OnClickListener.
1 private OnClickListener _OnClickListener = new OnClickListener() {
2 
3 		@Override
4 		public void onClick(View v) {
5 			Button btn = (Button) v;
6 			Toast.makeText(v.getContext(), "Premeches" + btn.getText(), Toast.LENGTH_SHORT).show();
7 		}
8 	};


  • Pasamos ese obxecto ás vistas que desexemos cando se faga Click nelas.
1 		Button boton5 = (Button) findViewById(R.id.boton5);
2 		boton5.setOnClickListener(_OnClickListener);
3 
4 		Button boton6 = (Button) findViewById(R.id.boton6);
5 		boton6.setOnClickListener(_OnClickListener);


onLongClick()

  • Cando sobre unha vista se preme por duración de 1 segundo o máis lánzase o evento LongClick que é capturado polo método onLongClick() asociado ao correspondente interface.
  • O método onLongClick() devolve un booleano para poder comprobar se o evento se consumou ou non. Se chegamos a premer por un segundo (ou máis) ou non.
    • Devolve true se puidemos capturar o evento e xa non fai nada máis.
    • Devolve false se non se puido capturar o evento e continua chamando a outros escoitadores tipo on-Click.


Caso Práctico

  • Comezamos creando o proxecto U3_03_OnLongClick
  • Esta actividade ten 2 vistas:
    • Un botón que se pode facer Click (usando a propiade do XML) e LongClick (capturado a través dun Listener)
    • Unha etiqueta de texto (en 2 liñas) na que se pode facer Click (hai que habilitalo) e LongClick. Nos dos casos os eventos captúranse con cadanseu Listener.

Android 2013 U3 03 OnLongClick 01.jpg


XML do Layout

  • Observar a Liña 20 onde se habilita o TextView para sexa clickable.
  • Agora poderíase engadir ao compoñente a propiedade: android:onClick="onBotonClick"
 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical" >
 6 
 7     <Button
 8         android:id="@+id/boton"
 9         android:layout_width="match_parent"
10         android:layout_height="wrap_content"
11         android:onClick="onBotonClick"
12         android:text="Botón:\n
13                       onClick Layout\n
14                       onLongClick Listener" />
15 
16     <TextView
17         android:id="@+id/text_view"
18         android:layout_width="match_parent"
19         android:layout_height="wrap_content"
20         android:clickable="true"
21         android:text="Fai click e
22                       \nPreme aquí por máis de 1 seg"
23         android:textSize="20sp" />
24 
25 </LinearLayout>

Código Java

 1 package com.example.u3_03_onlongclick;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.view.Menu;
 6 import android.view.View;
 7 import android.view.View.OnClickListener;
 8 import android.view.View.OnLongClickListener;
 9 import android.widget.Button;
10 import android.widget.TextView;
11 import android.widget.Toast;
12 
13 public class U3_03_OnLongClick extends Activity {
14 
15 	@Override
16 	protected void onCreate(Bundle savedInstanceState) {
17 		super.onCreate(savedInstanceState);
18 		setContentView(R.layout.activity_u3_03__on_long_click);
19 
20 		Button boton = (Button) findViewById(R.id.boton);
21 		boton.setOnLongClickListener(new OnLongClickListener() {
22 			@Override
23 			public boolean onLongClick(View v) {
24 				// TODO Auto-generated method stub
25 				Toast.makeText(v.getContext(), "Premeches 1 seg no botón", Toast.LENGTH_SHORT).show();
26 				return true;
27 			}
28 		});
29 
30 		
31 		
32 		TextView tv = (TextView) findViewById(R.id.text_view);
33 		tv.setOnLongClickListener(new OnLongClickListener() {
34 			@Override
35 			public boolean onLongClick(View v) {
36 				// TODO Auto-generated method stub
37 				Toast.makeText(v.getContext(), "Premeches 1 seg na etiqueta de texto", Toast.LENGTH_SHORT).show();
38 				return true;
39 			}
40 		});
41 
42 		tv.setOnClickListener(new OnClickListener() {
43 
44 			@Override
45 			public void onClick(View v) {
46 				// TODO Auto-generated method stub
47 				Toast.makeText(v.getContext(), "Fixeches click na etiqueta de texto", Toast.LENGTH_SHORT).show();
48 			}
49 		});
50 
51 	}
52 
53 	public void onBotonClick(View v) {
54 		Toast.makeText(this, "Fixeches Click no botón", Toast.LENGTH_SHORT).show();
55 	}
56 
57 	@Override
58 	public boolean onCreateOptionsMenu(Menu menu) {
59 		// Inflate the menu; this adds items to the action bar if it is present.
60 		getMenuInflater().inflate(R.menu.u3_03__on_long_click, menu);
61 		return true;
62 	}
63 
64 }
  • Liñas 21-28:
    • Cando se faga un LongClick en boton este executará o método onLonClick() que devolverá true se se chegou a consumar o evento.
    • Probar a cambiar a liña 26 a return false e executar a aplicación. Que pasa?


  • Liñas 33-40:
    • Acontece o mesmo que no caso anterior so que para a etiqueta de texto.


  • Liñas 42-49:
    • Se na etiqueta sucede o evento Click executase chámase ao Listener correspondente da etiqueta.





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