Acceder

Ver la Versión Completa : Duda con OnTouchListener


manolazo
18/03/14, 20:52:39
Buenas.
Me quede atascado en esta tonteria.
Resumiendo:
Construyo un Grilayout en ejecucion:



public void construirGridlayout(){

for (int i =0; i<NUM_FILAS;++i){
for (int j=0; j<NUM_COLUMNAS; ++j){
linear = new LinearLayout(this);
/*En cada LinearLaout meto dos imagenes
una con estado View.Visible y otra Gone*/

//A cada linearLayout le pongo un onTouchListener
linear.setOnTouchListener(new touchPiezas));
}
}
}


El listener en resumidas cuentas:


class touchPiezas implements View.OnTouchListener{
ImageView im1,im2;
@Override
public boolean onTouch(View view, MotionEvent event) {
LinearLayout linear= (LinearLayout)view;
im1= (ImageView) linear.getChildAt(0);
im2 = (ImageView) linear.getChildAt(1);

int action = event.getAction();

switch(action){
case MotionEvent.ACTION_DOWN :
/*Cuando dejo pulsado una imagen se de la vuelta y aparece la de abajo.*/
im1.setVisibility(View.GONE);
im2.setVisibility(View.VISIBLE);
break;

case MotionEvent.ACTION_UP:
/*Suelto el dedo y se revierte la situacion */
im1.setVisibility(View.VISIBLE);
im2.setVisibility(View.GONE);
break;
}
return true;
}
}


La cuestion es como hacer que no pueda pulsar una segunda o mas imagenes del grid hasta que no haya soltado el dedo de la que tengo pulsada???

Al hacer en el bucle linear.setOnTouchListener(new touchPiezas)); ,todas las imagenes tienen asignado un listener.

Quiero que cuando quite el dedo (MotionEvent.ACTION_UP:) si me permita pulsar otra imagen del grid, pero mientras este en MotionEvent.ACTION_DOWN no me lo permita.

No se si me explico.

Lo he intentado de diferentes metodos y no hay manera pero supongo que habra una forma sencilla.

Un saludo

kriogeN
18/03/14, 21:40:11
Puedes poner una variable booleana de clase (static) en touchPiezas, que se active con el ACTION_DOWN y se libere con el ACTION_UP (por cierto también deberías de contar cuantos dedos están pulsando la pantalla, y ejecutar sólo cuando sea 1). Y si la variable está activada cuando haces el ACTION_DOWN, no ejecutas el código.

manolazo
19/03/14, 00:12:45
Buenas.
Con event.getPointerCount() siempre retorna 1. Es normal ya que cada imagen lanza su propio onTouchListener. Ademas para que sea mas de 1 habria que poner mas de un dedo en cada imagen lo cual no viene al caso ya que son pequeñas. Ten en cuenta que es un grid de 3x3 y lo que interesa es que getPointerCount me retorne 2 cuando pulso sobre dos imagenes distintas.

Por otra parte si implemento public boolean onTouchEvent(MotionEvent event) para ver el numero de punteros , no retorna ningun valor cuando pulso sobre cualquier elemento del gridlayout.

Respecto a poner variable booleana tambien lo he intentado pero tampoco me sale.
Yo lo que hago es inicialiar : boolean tocado= false; y dentro de case MotionEvent.ACTION_DOWN
poner un if (!tocado){
tocado=true;
im1.setVisibility(View.GONE);
im2.setVisibility(View.VISIBLE);
}
En el action_UP lo cambio a true, pero no funciona con mas de un toque.

YO creo que con lo que comentas de que solo se ejecute si solo hay un dedo en pantalla deberia de funcionar pero...... no detecta varios dedos en el gridlayout.

kriogeN
19/03/14, 09:57:04
Ya, lo de los 2 dedos me refería a cada una de las imágenes, pero realmente tampoco funcionaría bien salvo que pusieses más controles, puedes probar otra cosa:

Usa un Integer inicializado a 0, y recuerda que tiene que ser static, sino no va a funcionar. Cada vez que se ejecuta el ACTION_DOWN sumas 1, y cada vez que se ejecuta el ACTION_UP restas 1. El código del ACTION_DOWN sólo lo ejecutas cuando la variable pase de 0 a 1 y el de ACTION_UP cuando pase de 1 a 0.

manolazo
19/03/14, 14:49:31
Hola lo solucione mucho mas enrevesado como dices pero mucho mejor tu solucion del contador aunque no entiendo muy bien lo de poner el integer como static porque dentro de la clase intenrna no se puede poner variable static sin que sea final : static integer contador=0; (habria que ponerla como final con lo cual seria una constante).
La puse sin ser static como variable global.

POr cierto y a modo de curiosidad. Por que si implemento este metodo:


@Override
public boolean onTouchEvent(MotionEvent event) {
System.out.println("Numero de punteros :"+event.getPointerCount();
return true;
}

No me retorna ningun valor si pulso sobre cada elemento del gridlayout? si pulso fuera del grid si me sale.

Un saludo

kriogeN
19/03/14, 15:37:58
Ahmm, vale, que es una clase interna, entonces si, lo puedes usar con una variable global en la clase general.

¿El onTouchEvent es sobre la Activity? Si es así, es lógico, porque los elementos del GridLayout tienen su propio onTouchListener y siempre devuelve true. Por eso el control no pasa al contenedor padre, y así sucesivamente hasta llegar a la Activity.

Si quieres que cuando se cumpla una determinada condición se ejecute el onTouchEvent de la Activity tendrás que hacer que el onTouchListener bajo esa condición devuelva false. Pero ten en cuenta que entonces nunca se ejecutará el código del ACTION_UP si ACTION_DOWN ha devuelto false.

manolazo
19/03/14, 18:20:54
Ok. Gracias por la explicación.
Un saludo