Drag & Drop

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

Introdución

  • NOTA: imos usar como SDK mínimo o 11.
  • Se necesitamos controlar a versión o podemos facer coa clase VERSION da seguinte forma:

String androidOS = Build.VERSION.RELEASE; if (androidOS.startsWith("2")) ==> versión 2.x.x


  • Con Drag & Drop (Arrastrar e soltar) permíteselle ao usuario que arrastre datos dende unha Vista á outra.
  • O proceso divídese en:
    • O proceso comeza cando o usuario realiza algún xesto nun obxecto que reconozamos como inicio do arrastre. Por exemplo: un LongClick
    • A aplicación informa ao SO que o proceso de arrastre comezou e indícalle que elemento (View) é o que ten que debuxar mentres se arrastra, que é un elemento distinto do que iniciamos o proceso (pode ser a mesma imaxe para que pareza que movemos algo)
    • Hai que definir os obxectos Views sobre os que se vai recibir o Drop (Soltar). Cando se comeza a arrastrar un obxecto o SO manda unha mensaxe a todos os elementos gráficos da nosa pantalla que poidan recibir un drop, esperando unha contestación de se aceptarán ou non os diferentes eventos que se poidan dar durante o arrastre (que o obxecto entre dentro do View, saia, solte,....)


Caso práctico sinxelo

  • Comezamos creando un proxecto: U3_20_DragDrop
  • Usaremos as seguintes imaxes no recurso /res/drawable

Ok.png No.png Question.png


  • O funcionamento da Activity é o seguinte:

Android 2013 U3 20 DragDrop 01.jpg

  • Ao facer un LongClick na pregunta pódese comezar a arrastrar.
  • En función do botón ao que se arrastre obtemos unha mensaxe que indica a que botón se arrastrou: OK ou NO.

XML do layout

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:id="@+id/LinearLayoutPreguntas"
 4     android:layout_width="match_parent"
 5     android:layout_height="match_parent"
 6     android:orientation="vertical" >
 7 
 8     <TextView
 9         android:layout_width="wrap_content"
10         android:layout_height="wrap_content"
11         android:text="Drag &amp; Drop"
12         android:layout_gravity="center"
13         android:textSize="22sp" />
14 
15     <ImageView
16         android:id="@+id/imgvwPreguntaArrastrar"
17         android:layout_width="match_parent"
18         android:layout_height="0dp"
19         android:layout_gravity="center_horizontal"
20         android:layout_weight="1"
21         android:contentDescription="Imaxe pregunta arrastrar"
22         android:src="@drawable/question" />
23 
24     <RelativeLayout
25         android:layout_width="match_parent"
26         android:layout_height="0dp"
27         android:layout_weight="5" >
28 
29         <ImageView
30             android:id="@+id/imgVwPreguntasNo"
31             android:layout_width="wrap_content"
32             android:layout_height="wrap_content"
33             android:layout_alignParentRight="true"
34             android:layout_alignTop="@+id/imgvwPreguntasOk"
35             android:contentDescription="Imaxe preguntas NO"
36             android:src="@drawable/no" />
37 
38         <ImageView
39             android:id="@+id/imgvwPreguntasOk"
40             android:layout_width="wrap_content"
41             android:layout_height="wrap_content"
42             android:layout_alignParentLeft="true"
43             android:layout_centerVertical="true"
44             android:contentDescription="Imaxe preguntas OK"
45             android:src="@drawable/ok" />
46     </RelativeLayout>
47 
48 </LinearLayout>


Cógigo Java da Aplicación

  • A continuación debullamos o código:
  1 package com.example.u3_20_dragdrop;
  2 
  3 import android.app.Activity;
  4 import android.os.Build;
  5 import android.os.Bundle;
  6 import android.view.DragEvent;
  7 import android.view.Menu;
  8 import android.view.View;
  9 import android.view.View.DragShadowBuilder;
 10 import android.view.View.OnLongClickListener;
 11 import android.view.ViewGroup;
 12 import android.widget.ImageView;
 13 import android.widget.Toast;
 14 
 15 public class U3_20_DragDrop extends Activity {
 16 
 17 	@Override
 18 	protected void onCreate(Bundle savedInstanceState) {
 19 		super.onCreate(savedInstanceState);
 20 		setContentView(R.layout.activity_u3_20__drag_drop);
 21 
 22 		String androidOS = Build.VERSION.RELEASE;
 23 		if (!(androidOS.startsWith("2")) && !(androidOS.startsWith("1")))
 24 			xestionarArrastrar();
 25 
 26 	}
 27 
 28 	private void xestionarArrastrar() {
 29 		ImageView pregunta = (ImageView) findViewById(R.id.imgvwPreguntaArrastrar);
 30 
 31 		// Xestionamos cando prememos durante un tempo maior a 1 seg.
 32 		pregunta.setOnLongClickListener(new OnLongClickListener() {
 33 
 34 			@Override
 35 			public boolean onLongClick(View v) {
 36 				// TODO Auto-generated method stub
 37 				DragShadowBuilder sombra = new DragShadowBuilder(v);
 38 				v.startDrag(null, sombra, null, 0);
 39 				v.setVisibility(View.INVISIBLE);
 40 				return true;
 41 			}
 42 		});
 43 
 44 
 45                View.OnDragListener _OnDragListener = new View.OnDragListener() {
 46  
 47                         @Override
 48                         public boolean onDrag(View arg0, DragEvent arg1) {
 49                                 ImageView pregunta = (ImageView) findViewById(R.id.imgvwPreguntaArrastrar);
 50  
 51                                 // Este método vaise chamar 3 veces: ao soltar a imaxe pregunta
 52                                 // ou na imaxe OK
 53                                 // ou na imaxe NO
 54                                 // ou no Layout
 55                                 if (arg1.getAction() == DragEvent.ACTION_DRAG_STARTED) {
 56  
 57                                         return true; // Aceptamos xestionar os eventos
 58  
 59                                 }
 60                                 if (arg1.getAction() == DragEvent.ACTION_DRAG_ENTERED) {
 61                                    // Para cambiar de imaxe ó entrar
 62                                    //((ImageView)arg0).setImageResource(R.drawable.imaxeoentrar);
 63                                 }
 64                                 if (arg1.getAction() == DragEvent.ACTION_DRAG_EXITED) {
 65                                   // Para cambiar de imaxe o ó saír
 66                                   //((ImageView)arg0).setImageResource(R.drawable.imaxeosair);
 67                                 }
 68                                 if (arg1.getAction() == DragEvent.ACTION_DROP) { 
 69                                     // Soltamos a imaxe pregunta
 70  
 71                                         // COMPROBAMOS EN QUE IMAXE SE SOLTOU: OK, NO ou Layout
 72                                         switch (arg0.getId()) {
 73                                         case R.id.imgvwPreguntasOk:
 74                                                 Toast.makeText(getApplicationContext(), "Soltaches en OK", Toast.LENGTH_SHORT).show();
 75  
 76                                                 break;
 77                                         case R.id.imgVwPreguntasNo:
 78                                                 Toast.makeText(getApplicationContext(), "Soltaches en NO", Toast.LENGTH_SHORT).show();
 79                                                 break;
 80                                         default:
 81                                                // FACEMOS VISIBLE A IMAXE DA PREGUNTA 
 82                                                // Soltouse a imaxe no layout
 83                                                 pregunta.setVisibility(View.VISIBLE);
 84                                                 return false;
 85                                         }
 86  
 87                                         // FACEMOS VISIBLE A IMAXE PREGUNTA
 88                                         pregunta.setVisibility(View.VISIBLE);
 89                                         return true;
 90                                 }
 91                                 return false;
 92                         }
 93                 };
 94 
 95 		// Asociamos os obxectos ImageView e Layout á interface definida antes.
 96 		ImageView imgOk = (ImageView) findViewById(R.id.imgvwPreguntasOk);
 97 		ImageView imgNo = (ImageView) findViewById(R.id.imgVwPreguntasNo);
 98 		ViewGroup pantalla = (ViewGroup) findViewById(R.id.LinearLayoutPreguntas);
 99 
100 		imgNo.setOnDragListener(_OnDragListener);
101 		imgOk.setOnDragListener(_OnDragListener);
102 		pantalla.setOnDragListener(_OnDragListener);
103 
104 	}
105 
106 	@Override
107 	public boolean onCreateOptionsMenu(Menu menu) {
108 		// Inflate the menu; this adds items to the action bar if it is present.
109 		getMenuInflater().inflate(R.menu.u3_20__drag_drop, menu);
110 		return true;
111 	}
112 
113 }


Comprobar versión de Android

  • Comprobamos se a versión de Android e 3.x.x ou superior, nese caso chamamos ao método que vai xestionar o Drag&Drop.
1                 String androidOS = Build.VERSION.RELEASE;
2                 if (!(androidOS.startsWith("2")) && !(androidOS.startsWith("1")))
3                         xestionarArrastrar();

Comezar a arrastrar

 1                 ImageView pregunta = (ImageView) findViewById(R.id.imgvwPreguntaArrastrar);
 2  
 3                 // Xestionamos cando prememos durante un tempo maior a 1 seg.
 4                 pregunta.setOnLongClickListener(new OnLongClickListener() {
 5  
 6                         @Override
 7                         public boolean onLongClick(View v) {
 8                                 // TODO Auto-generated method stub
 9                                 DragShadowBuilder sombra = new DragShadowBuilder(v);
10                                 v.startDrag(null, sombra, null, 0);
11                                 v.setVisibility(View.INVISIBLE);
12                                 return true;
13                         }
14                 });
  • Se na imaxe da pregunta se fai un LongClick capturamos ese evento cun Listener e
  • Indicámoslle ao S.O. o que ten que debuxar cando faga Drag sobre a imaxe.
  • Para debuxar a imaxe (ou o que queiramos) que vai a moverse pola pantalla, temos que utilizar un obxecto da clase DragShadowBuilder.
  • Podemos crear unha subclase de dita clase e personalizar todo o que queiramos.
  • Para o noso exemplo, imos a usar a mesma imaxe da pregunta que está en pantalla para facelo.
  • Para iso só temos que crear un obxecto da clase DragShadowBuilder e pasarlle no constructor o View a debuxar pola pantalla. Neste caso o View asociado a imaxe da pregunta.
    • DragShadowBuilder sombra = new DragShadowBuilder(v);


  • Cando facemos un Drop, pode ser que veñan outros obxectos doutras aplicacións ou incluso da nosa, pero que non sexa o obxecto esperado.
  • Podemos facer que coa imaxe que se arrastra, vaia asociado información dun tipo determinado, de tal forma que o obxecto que vai a recibir a imaxe (drop,) pode preguntar polo tipo de información que acompaña a imaxe (ou o que se estea arrastrando) e se non é do tipo que espera dicirlle o S.O. que non quere recibir máis eventos do obxecto que se arrastra.
    • Neste exemplo non imos asociar información á imaxe.


  • Chamamos ao método startDrag(): v.startDrag(null, sombra, null, 0);
  • Ten catro parámetros:
    • O primeiro: é onde iría a información que acompañaría á imaxe.
    • O segundo: é o obxecto da clase DragShadowBuilder (A vista que se vai mover pola pantalla)
    • O terceiro: serve para o mesmo que o primeiro pero cun tipo de información máis sinxela.
    • O cuarto: non se utiliza.


  • v.setVisibility(View.INVISIBLE) fai que a vista que conteń a imaxe na súa posición inicial non sexa visible.
    • Lembrar que o que aparece visualmente como obxecto que se move pola pantalla non é o orixinal.


  • Finalmente o método onLongClick devolve true se realmente se consumou o evento LongClick.

Vistas nas que soltar

  • Agora hai que informar o S.O. sobre que obxectos van poder recibir operacións de Drop.
  • Cada unha das vistas receptoras (contenedoras) do Drop terá que ter asociado a interface OnDragListener, polo que terán que chamar o método setOnDragListener.
  • Como queremos que todos elas (as contedoras) teñan o mesmo código, podemos usar un obxecto da clase onDragListener para facelo (Visto no apartado de Xestión de Eventos III)
1                 ImageView imgOk = (ImageView) findViewById(R.id.imgvwPreguntasOk);
2                 ImageView imgNo = (ImageView) findViewById(R.id.imgVwPreguntasNo);
3                 ViewGroup pantalla = (ViewGroup) findViewById(R.id.LinearLayoutPreguntas);
4  
5                 imgNo.setOnDragListener(_OnDragListener);
6                 imgOk.setOnDragListener(_OnDragListener);
7                 pantalla.setOnDragListener(_OnDragListener);
  • Os 2 botóns e o layout poden ser recptores da imaxe que se anda arrastrando pola pantalla, como hai que facer case o mesmo nos tres casos, crease un obxecto que implemente o método onDrag() do interface OnDragListener.


O método onDrag. Implementar o Interface

  • Este evento é chamado cando se solta unha vista sobre outra, e é esta última quen o chama.


 1 View.OnDragListener _OnDragListener = new View.OnDragListener() {
 2  
 3                         @Override
 4                         public boolean onDrag(View arg0, DragEvent arg1) {
 5                                 ImageView pregunta = (ImageView) findViewById(R.id.imgvwPreguntaArrastrar);
 6  
 7                                 // Este método vaise chamar 3 veces: ao soltar a imaxe pregunta
 8                                 // ou na imaxe OK
 9                                 // ou na imaxe NO
10                                 // ou no Layout
11                                 if (arg1.getAction() == DragEvent.ACTION_DRAG_STARTED) {
12  
13                                         return true; // Aceptamos xestionar os eventos
14  
15                                 }
16                                 if (arg1.getAction() == DragEvent.ACTION_DRAG_ENTERED) {
17                                    // Para cambiar de imaxe ó entrar
18                                    //((ImageView)arg0).setImageResource(R.drawable.imaxeoentrar);
19                                 }
20                                 if (arg1.getAction() == DragEvent.ACTION_DRAG_EXITED) {
21                                   // Para cambiar de imaxe o ó saír
22                                   //((ImageView)arg0).setImageResource(R.drawable.imaxeosair);
23                                 }
24                                 if (arg1.getAction() == DragEvent.ACTION_DROP) { 
25                                     // Soltamos a imaxe pregunta
26  
27                                         // COMPROBAMOS EN QUE IMAXE SE SOLTOU: OK, NO ou Layout
28                                         switch (arg0.getId()) {
29                                         case R.id.imgvwPreguntasOk:
30                                                 Toast.makeText(getApplicationContext(), "Soltaches en OK", Toast.LENGTH_SHORT).show();
31  
32                                                 break;
33                                         case R.id.imgVwPreguntasNo:
34                                                 Toast.makeText(getApplicationContext(), "Soltaches en NO", Toast.LENGTH_SHORT).show();
35                                                 break;
36                                         default:
37                                                // FACEMOS VISIBLE A IMAXE DA PREGUNTA 
38                                                // Soltouse a imaxe no layout
39                                                 pregunta.setVisibility(View.VISIBLE);
40                                                 return false;
41                                         }
42  
43                                         // FACEMOS VISIBLE A IMAXE PREGUNTA
44                                         pregunta.setVisibility(View.VISIBLE);
45                                         return true;
46                                 }
47                                 return false;
48                         }
49                 };
  • Creamos o obxecto _OnDragListener.
  • Implementamos o método onDrag(View arg0, DragEvent arg1)
  • Ten dous parámetros:
    • Un view que é quen recibe o a vista a soltar
    • un obxecto da clase DragEvent, que entre outras cousas nos podería servir para recoller a información que puidese acompañar á vista que arrastramos. Tamén serve para ver que acción se está realizando co elemento que se está arrastrando sobre a vista:
      • Entrando no obxecto destino, saíndo, soltando, etc.
    • Para saber o tipo de acción drag&drop que se produce, temos que usar o método getAction() da clase DragEvent.
        • Seguindo os comentarios do código pódense ver posibles accións se están levando a cabo co obxecto que se está arrastrando.


  • Se o evento que se produce é o Drop (Soltar):if (arg1.getAction() == DragEvent.ACTION_DROP)
  • Entón debemos executar o código que desexamos.
  • Como temos un obxecto _OnDragListener para tódalas posibles vistas destinarias temos que comprobar en que vista se soltou a imaxe e actuar en consecuencia.


  • Observar como facemos visible a imaxe inicial da pregunta unha vez que imos saír do método().


  • O return é moi importante, xa que cando prememos sobre a pregunta para arrastrala, o S.O. manda unha mensaxe a todas as Views que poden recoller un "Drag" (no noso caso OK, NO) preguntando quen quere aceptar o view que se vai arrastrar.
  • Se o procedemento onDrag devolve false, o S.O. non manda máis eventos a dito View, se devolve True si.



Caso práctico 2: Preguntas

  • Comezaremos creando un novo proxecto: U3_21_Preguntas
  • Neste caso baseándonos na aplicación anterior imos crear unha nova na que o sistema terá un array de preguntas (Verdadeiro/Falso) que amosara ao usuario de forma aleatoria.
  • O usuario debe responder arrastrando a imaxe da pregunta cara a imaxe OK ou NO.
  • A aplicación informará se a resposta é correcta ou non.
  • Unha vez que se acaben as preguntas informarase desa situación.

Android 2013 U3 21 Preguntas 01.jpg Android 2013 U3 21 Preguntas 02.jpg

  • No exemplo respondeuse mal á pregunta da primeira imaxe.
  • Na segunda imaxe xa se amosa unha nova pregunta e o informe da aplicación á nosa anterior resposta.

O XML do Layout

  • Nas liñas 15-29 están os Elementos que van amosar as preguntas.
 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:id="@+id/LinearLayoutPreguntas"
 4     android:layout_width="match_parent"
 5     android:layout_height="match_parent"
 6     android:orientation="vertical" >
 7 
 8     <TextView
 9         android:layout_width="wrap_content"
10         android:layout_height="wrap_content"
11         android:layout_gravity="center"
12         android:text="Drag &amp; Drop: Preguntas"
13         android:textSize="22sp" />
14 
15     <ScrollView
16         android:layout_width="match_parent"
17         android:layout_height="0dp"
18         android:layout_weight="3" >
19 
20         <TextView
21             android:id="@+id/lblPregunta"
22             android:layout_width="wrap_content"
23             android:layout_height="wrap_content"
24             android:layout_gravity="center"
25             android:gravity="center_horizontal"
26             android:text="Aquí van as preguntas"
27             android:textColor="#00F"
28             android:textSize="26sp" />
29     </ScrollView>
30 
31     <ImageView
32         android:id="@+id/imgvwPreguntaArrastrar"
33         android:layout_width="match_parent"
34         android:layout_height="0dp"
35         android:layout_gravity="center_horizontal"
36         android:layout_weight="1"
37         android:contentDescription="Imaxe pregunta arrastrar"
38         android:src="@drawable/question" />
39 
40     <RelativeLayout
41         android:layout_width="match_parent"
42         android:layout_height="0dp"
43         android:layout_weight="2" >
44 
45         <ImageView
46             android:id="@+id/imgVwPreguntasNo"
47             android:layout_width="wrap_content"
48             android:layout_height="wrap_content"
49             android:layout_alignParentRight="true"
50             android:layout_alignTop="@+id/imgvwPreguntasOk"
51             android:contentDescription="Imaxe preguntas NO"
52             android:src="@drawable/no" />
53 
54         <ImageView
55             android:id="@+id/imgvwPreguntasOk"
56             android:layout_width="wrap_content"
57             android:layout_height="wrap_content"
58             android:layout_alignParentLeft="true"
59             android:layout_centerVertical="true"
60             android:contentDescription="Imaxe preguntas OK"
61             android:src="@drawable/ok" />
62     </RelativeLayout>
63 
64 </LinearLayout>

Cógigo Java

  • Unha posible solución é a que se amosa a continuación.
  • Imos separar o código:
    • Lóxica do programa por un lado
      • Cando facemos unha aplicación, normalmente imos traballar con datos que temos que almacenar nalgún sitio. Na aplicación que estamos a desenvolver atopámonos coas preguntas. Todas as preguntas virán dunha táboa e teremos que recuperalas para amosalas ao usuario no xogo das preguntas.
      • Para facer máis claro o proxecto, imos crear un paquete onde gardaremos estas clases 'especiais'. Dentro de dito paquete teremos:
        • A clase Pregunta que terá todo o necesario para gardar a información dunha pregunta (id, enunciado, unha variable booleana que indique cal é a resposta correcta, outra variable booleana que indique se a pregunta foi lida).
        • Unha clase que sirva para gardar aquela información que teña que ver coa configuración do xogo e tamén que teña métodos que nos sirvan para o desenvolvemento do mesmo.
          • Gardar nun array o conxunto de preguntas que imos usar.
          • Un método que devolva unha pregunta que non fose lida do array anterior.


    • Activities polo outro
      • Cando facemos unha aplicación, normalmente imos traballar con datos que temos que almacenar nalgún sitio. Na aplicación que estamos a desenvolver nos atopamos coas preguntas. Todas as preguntas virán dunha táboa e teremos que recuperalas para amosalas ao usuario no xogo das preguntas.
  • Imos crear un Paquete para albergar a lóxica da aplicación:

Android 2013 U3 21 Preguntas 03.jpg

  • Na imaxe podemos ver que no paquete ...loxica hai dúas clases Java,
  • Para crear un paquete/clase: Co botón dereito sobre /src ou sobre o paquete indicar New --> Class

Android 2013 U3 21 Preguntas 04.jpg

  • Cubrir os campos do paquete e do nome da nova clase.

Clase Pregunta

  • Conten os atributos que pode ter unha pregunta e os métodos Setter e Getter dos atributos, así como unha sobre escritura do método toString();


 1 package com.example.u3_21_preguntas.loxica;
 2 
 3 public class Pregunta {
 4 	private int _id;
 5 	private String enunciado;
 6 	private boolean resposta;
 7 	private boolean vista; //Almacena se a pregunta xa foi amosada ao usuario
 8 
 9 	public Pregunta(int id, String enunciado, boolean resposta) {
10 		this._id = id;
11 		this.enunciado = enunciado;
12 		this.resposta = resposta;
13 		vista = false;
14 	}
15 
16 	public long get_id() {
17 		return _id;
18 	}
19 
20 	public void set_id(int _id) {
21 		this._id = _id;
22 	}
23 
24 	public String getEnunciado() {
25 		return enunciado;
26 	}
27 
28 	public void setEnunciado(String enunciado) {
29 		this.enunciado = enunciado;
30 	}
31 
32 	public boolean isResposta() {
33 		return resposta;
34 	}
35 
36 	public void setResposta(boolean resposta) {
37 		this.resposta = resposta;
38 	}
39 
40 	public boolean isVista() {
41 		return vista;
42 	}
43 
44 	public void setVista(boolean vista) {
45 		this.vista = vista;
46 	}
47 
48 	@Override
49 	public String toString() {
50 		return enunciado;
51 	}
52 }



Clase LoxicaXogoPreguntas

 1 package com.example.u3_21_preguntas.loxica;
 2 
 3 import java.util.ArrayList;
 4 import java.util.Random;
 5 
 6 public class LoxicaXogoPreguntas {
 7 
 8 	public static ArrayList<Pregunta> preguntas = new ArrayList<Pregunta>();
 9 
10 	public static int xerarAleatorio(int min, int max) {
11 		Random aleat = new Random();
12 		return (aleat.nextInt(max - min) + min);
13 	}
14 
15 	public static Pregunta obterNovaPregunta() {
16 
17 		boolean quedan = false;
18 		for (Pregunta pregunta : preguntas) {
19 			if (!pregunta.isVista()) {
20 				quedan = true;
21 				break;
22 			}
23 		}
24 		if (!quedan)
25 			return null;
26 
27 		int aleaotorio = xerarAleatorio(0, preguntas.size());
28 		Pregunta pregunta;
29 		do {
30 			pregunta = preguntas.get(aleaotorio);
31 			aleaotorio = xerarAleatorio(0, preguntas.size());
32 		} while (pregunta.isVista());
33 		return pregunta;
34 
35 	}
36 
37 }
  • Liña 8: preguntas como un array de obxectos de tipo Pregunta.


  • Método xerarAleatorio(): devolve un número aleatorio entre un mínimo e un máximo
  • Método obterNovaPregunta(): Revisa no array se quedan preguntas sen amosar e se é asi busca unha nova aleatoriamente e devolve esa Pregunta a que lle pedira unha pregunta nova


Clase Activity Preguntas

  • Importamos as 2 clases anteriores (Liñas 15,16)


  1 package com.example.u3_21_preguntas;
  2 
  3 import android.app.Activity;
  4 import android.os.Bundle;
  5 import android.view.DragEvent;
  6 import android.view.Menu;
  7 import android.view.View;
  8 import android.view.View.DragShadowBuilder;
  9 import android.view.View.OnLongClickListener;
 10 import android.view.ViewGroup;
 11 import android.widget.ImageView;
 12 import android.widget.TextView;
 13 import android.widget.Toast;
 14 
 15 import com.example.u3_21_preguntas.loxica.LoxicaXogoPreguntas;
 16 import com.example.u3_21_preguntas.loxica.Pregunta;
 17 
 18 public class U3_21_Preguntas extends Activity {
 19 	Pregunta preguntaActual = null;
 20 
 21 	@Override
 22 	protected void onCreate(Bundle savedInstanceState) {
 23 		super.onCreate(savedInstanceState);
 24 		setContentView(R.layout.activity_u3_21__preguntas);
 25 
 26 		crearPreguntas();
 27 		xestionarArrastrar();
 28 
 29 	}
 30 
 31 	private void xestionarArrastrar() {
 32 		ImageView pregunta = (ImageView) findViewById(R.id.imgvwPreguntaArrastrar);
 33 
 34 		// Xestionamos cando prememos durante un tempo maior a 1 seg.
 35 		pregunta.setOnLongClickListener(new OnLongClickListener() {
 36 
 37 			@Override
 38 			public boolean onLongClick(View v) {
 39 				// TODO Auto-generated method stub
 40 				DragShadowBuilder sombra = new DragShadowBuilder(v);
 41 				v.startDrag(null, sombra, null, 0);
 42 				v.setVisibility(View.INVISIBLE);
 43 				return true;
 44 			}
 45 		});
 46 
 47 		View.OnDragListener _OnDragListener = new View.OnDragListener() {
 48 
 49 			@Override
 50 			public boolean onDrag(View arg0, DragEvent arg1) {
 51 				ImageView pregunta = (ImageView) findViewById(R.id.imgvwPreguntaArrastrar);
 52 
 53 				// Este método vaise chamar 3 veces: ao soltar a imaxe pregunta
 54 				// ou na imaxe OK
 55 				// ou na imaxe NO
 56                                 // ou Layout
 57 				if (arg1.getAction() == DragEvent.ACTION_DRAG_STARTED) {
 58 
 59 					return true; // Aceptamos xestionar os eventos
 60 				}
 61 				if (arg1.getAction() == DragEvent.ACTION_DRAG_ENTERED) {
 62 				}
 63 				if (arg1.getAction() == DragEvent.ACTION_DRAG_EXITED) {
 64 				}
 65 				if (arg1.getAction() == DragEvent.ACTION_DROP) { 
 66                                          // Soltamos a imaxe pregunta
 67 
 68 					// COMPROBAMOS EN QUE IMAXE SE SOLTOU: ok, no ou layout
 69 					switch (arg0.getId()) {
 70 					case R.id.imgvwPreguntasOk:
 71 						comprobarPregunta(true);
 72 
 73 						break;
 74 					case R.id.imgVwPreguntasNo:
 75 						comprobarPregunta(false);
 76 						break;
 77 					default:
 78 						pregunta.setVisibility(View.VISIBLE);
 79 						return false;
 80 					}
 81 
 82 					// FACEMOS VISIBLE A IMAXE PREGUNTA
 83 					pregunta.setVisibility(View.VISIBLE);
 84 					return true;
 85 				}
 86 				return false;
 87 			}
 88 		};
 89 
 90 		// Asociamos os obxectos ImageView e Layout á interface definida antes.
 91 		ImageView imgOk = (ImageView) findViewById(R.id.imgvwPreguntasOk);
 92 		ImageView imgNo = (ImageView) findViewById(R.id.imgVwPreguntasNo);
 93 		ViewGroup pantalla = (ViewGroup) findViewById(R.id.LinearLayoutPreguntas);
 94 
 95 		imgNo.setOnDragListener(_OnDragListener);
 96 		imgOk.setOnDragListener(_OnDragListener);
 97 		pantalla.setOnDragListener(_OnDragListener);
 98 	}
 99 
100 	private void cambiarPregunta() {
101 		Pregunta preguntaSeguinte = LoxicaXogoPreguntas.obterNovaPregunta();
102 		if (preguntaSeguinte == null) {
103 			Toast.makeText(getApplicationContext(), "Non hai máis preguntas", Toast.LENGTH_LONG).show();
104 			preguntaActual = null;
105 		} else {
106 
107 			preguntaActual = preguntaSeguinte;
108 			preguntaActual.setVista(true);
109 
110 			TextView texto = (TextView) findViewById(R.id.lblPregunta);
111 
112 			texto.setText(preguntaActual.getEnunciado());
113 		}
114 
115 	}
116 
117 	private void crearPreguntas() {
118 		// Creamos tres preguntas e metémolas no array de preguntas
119 		Pregunta pregunta1 = new Pregunta(0, "Está o sol cerca ?", false);
120 		Pregunta pregunta2 = new Pregunta(1, "É a lúa un satélite ?", true);
121 		Pregunta pregunta3 = new Pregunta(2, "A velocidade da luz é de 300.000 km/seg ?", true);
122 
123 		LoxicaXogoPreguntas.preguntas.add(pregunta1);
124 		LoxicaXogoPreguntas.preguntas.add(pregunta2);
125 		LoxicaXogoPreguntas.preguntas.add(pregunta3);
126 
127 		cambiarPregunta();
128 	}
129 
130 	private void comprobarPregunta(boolean resposta) {
131 		if (preguntaActual.isResposta() == resposta)
132 			Toast.makeText(getApplicationContext(), "Parabéns acertaches", Toast.LENGTH_SHORT).show();
133 
134 		else
135 			Toast.makeText(getApplicationContext(), "Hmmm! Fallaches", Toast.LENGTH_SHORT).show();
136 
137 		cambiarPregunta();
138 
139 	}
140 
141 	@Override
142 	public boolean onCreateOptionsMenu(Menu menu) {
143 		// Inflate the menu; this adds items to the action bar if it is present.
144 		getMenuInflater().inflate(R.menu.u3_21__preguntas, menu);
145 		return true;
146 	}
147 
148 }
  • Liña 19: creamos unha variable preguntaActual para saber que pregunta estamos procesando.
  • Liña 26: Chamamos ao método para crear as preguntas
  • Liñas 117...: Método crearPreguntas: Creamos as preguntas e engadímolas ao array de Preguntas. Cando finalicemos de crear as preguntas chamamos ao método que vaia cambiando as preguntas que se van amosando.
    • O ideal sería traballar con ficheiros ou unha BD como se verá máis adiante.
  • Liñas 100...: Método cambiarPreguntas: busca a pregunta seguinte, se non hai máis preguntas saca un aviso, en caso contrario amosa en pantalla a nova pregunta.
  • Liñas 130...: Método comprobarPregunta: é chamado cando se solta a imaxe da pregunta nunha das imaxes (OK/NO).
    • Recibe como parámetro true/false en función do botón no que fose soltada a imaxe.
    • Compárase a resposta dada coa resposta gardada na pregunta e actúase en consecuencia ...




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