2010-03-29 13 views
11

Mi clase extiende la vista y necesito obtener eventos táctiles continuos sobre ella.¿Cómo obtener un evento táctil continuo?

si uso:

public boolean onTouchEvent(MotionEvent me) { 

    if(me.getAction()==MotionEvent.ACTION_DOWN) { 
     myAction(); 
    } 
    return true; 
} 

... el evento táctil se captura una vez.

¿Qué sucede si necesito obtener toques continuos sin mover el dedo? Por favor, dime que no necesito usar hilos o temporizadores. Mi aplicación ya es demasiado pesada.

Gracias.

Respuesta

15

Utilice if(me.getAction() == MotionEvent.ACTION_MOVE). Es imposible mantener un dedo al 100% completamente quieto en la pantalla, por lo que se llamará a Action_Move cada vez que se mueve el dedo, incluso si solo es un píxel o dos.

También puede escuchar me.getAction() == MotionEvent.ACTION_UP - hasta que eso suceda, el usuario aún debe tener el dedo en la pantalla.

+2

correcta, yo preferiría la solución para establecer un indicador en ACTION_DOWN y el uso que hasta que se establece el indicador a falso en ACTION_UP – WarrenFaith

+0

Realmente gracias. – daliz

+0

Veo esto mencionado en todas partes pero no parece ser el caso para mí. Si toco y me quedo y me quedo quieto, no recibo eventos de ACTION_MOVE. ACTION_MOVE solo parece activarse si inclino mi dedo hacia un lado o hacia el otro. ¿Podría ser una configuración en mi teléfono que lo mantiene menos sensible? – clusterflux

3

Her es el fragmento de código simple que muestra cómo puede manejar el evento táctil continúa. Cuando toque el dispositivo, mantenga presionado el botón táctil y mueva el buscador, se ejecutará la acción Touch Move.

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    float x = event.getX(); 
    float y = event.getY(); 
    if(isTsunami){ 
    switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      // Write your code to perform an action on down 
      break; 
     case MotionEvent.ACTION_MOVE: 
      // Write your code to perform an action on contineus touch move 
      break; 
     case MotionEvent.ACTION_UP: 
      // Write your code to perform an action on touch up 
      break; 
    } 
    } 
    return true; 
} 
1

Pruebe esto. Se trabaja para mí:

public static OnTouchListener loadContainerOnTouchListener() { 
    OnTouchListener listener = new OnTouchListener(){ 
    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     LinearLayout layout = (LinearLayout)v; 
     for(int i =0; i< layout.getChildCount(); i++) 
     { 
      View view = layout.getChildAt(i); 
      Rect outRect = new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom()); 
      if(outRect.contains((int)event.getX(), (int)event.getY())) 
      { 
       Log.d(this.getClass().getName(), String.format("Over view.id[%d]", view.getId())); 
      } 
     } 

    } 

Recuerde: el conjunto you'll oyente debe ser un diseño de envase (Grid, relativa, lineal).

LinearLayout layout = findViewById(R.id.yourlayoutid); 
layout.setOnTouchListener(HelperClass.loadContainerOnTouchListener()); 
5

Es necesario configurar estas propiedades para el androide elemento : enfocable = "true" androide: se puede hacer clic = "true" si no, simplemente producir la acción hacia abajo.

0

Estaba haciendo un juego con una vista personalizada utilizada como control de pulgar. . . esto es lo que hice

float x = 0, y = 0; 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    x = event.getX(); 
    y = event.getY(); 

    // handle touch events with 
    switch(event.getActionMasked()) { 
     case MotionEvent.ACTION_DOWN : 
      if(cont) 
      { 
       // remove any previous callbacks 
       removeCallbacks(contin); 

       // post new runnable 
       postDelayed(contin, 10); 
      } 
      invalidate(); 
      return true; 
     case MotionEvent.ACTION_MOVE : 
      if(!cont && thumbing != null) 
      { 
       // do non-continuous operations here 
      } 
      invalidate();  
      return true; 
     case MotionEvent.ACTION_UP : 

      // set runnable condition to false 
      x = 0; 

      // remove the callbacks to the thread 
      removeCallbacks(contin); 
      invalidate(); 
      return true; 
     default : 
      return super.onTouchEvent(event); 
    } 
} 

public boolean cont = false; 

// sets input to continuous 
public void set_continuous(boolean b) { cont = b; } 


public Runnable contin = new Runnable() 
{ 

    @Override 
    public void run() { 
     if(x != 0) 
     { 
      // do continuous operations here 
      postDelayed(this, 10); 
     } 
    } 

}; 

Una nota rápida sin embargo, asegúrese de que en la actividad principal que se llama a este punto de vista elimina las devoluciones de llamada de forma manual a través del método onPause de la siguiente manera

@Override 
protected void onPause() { 
    if(left.cont) left.removeCallbacks(left.contin); 
    if(right.cont) right.removeCallbacks(left.contin); 
    super.onPause(); 
} 

De esa manera si hace una pausa y volver eventos táctiles no se manejan dos veces y la vista es libre de su sobrecarga.

** probado en galaxia S3 con la aceleración de hardware en **

0

Todas estas respuestas son parcialmente correcta, pero no resuelven de la manera correcta el problema.

En primer lugar, para todos los que decidan seguir cuando el evento es ACTION_MOVE. Bueno, eso solo funciona adivinar cuándo? Cuando el usuario mueve su dedo, también podría hacerlo si decide implementar un control de pulgar personalizado, pero para un botón personalizado normal ese no es el caso.

En segundo lugar, el uso de una bandera dentro ACTION_DOWN y comprobar que en ACTION_UP parece la forma lógica para hacerlo, pero como Clusterfux averiguar si la aplicación de una lógica while(!up_flag) se queda atascado en problemas;)

Así que la forma correcta para hacerlo se menciona aquí:

Continuous "Action_DOWN" in Android

Hemos de tener en cuenta que si la lógica se va a escribir en la prensa continua tiene que modificar la interfaz de usuario de alguna manera, hay que hacerlo desde la hilo principal en todos los otros casos, es mejor utilizar otro hilo.

0

Esto podría ayudar,

requestDisallowInterceptTouchEvent(true); 

en la vista padre, como esto -

 @Override 
     public boolean onTouch(View view, MotionEvent motionEvent) { 
      view.getParent().requestDisallowInterceptTouchEvent(true); 
      switch(motionEvent.getActio){ 
      } 

      return false; 

     } 
Cuestiones relacionadas