2010-07-13 17 views
5

Sto facendo un gioco su Android e ho bisogno di fare determinate azioni quando gli utenti tentano una lunga pressione sullo schermo. Purtroppo non ho trovato alcun metodo che funzioni direttamente con un SurfaceView personalizzato, sentitevi liberi di dirmi se esiste un tale metodo :)Long Touch su una superficieView (android)

Così ho deciso di provare e implementare un rilevamento di tocco lungo dal listener di eventi onTouch.

Ecco il mio codice:

@Override 
    public boolean onTouch(View v, MotionEvent event) 
    { 
     long touchDuration = 0; 


      if (event.getAction() == MotionEvent.ACTION_DOWN) 
      { 
       //Start timer 
       touchTime = System.currentTimeMillis(); 


      }else if (event.getAction() == MotionEvent.ACTION_UP) 
      { 
       //stop timer 
       touchDuration = System.currentTimeMillis() - touchTime; 

       if (touchDuration < 800) 
       { 
        onShortTouch(event,touchDuration); 
       }else 
       { 
        onLongTouch(event,touchDuration); 
       } 
      } 
     } 

     return true; 

Questo funziona, ma in grado di rilevare se la stampa è stata una pressione prolungata o non solo quando l'utente smette di toccare il telefono. Quindi non è esattamente quello che voglio. Preferirei che un timer si avvii quando l'utente tocca per la prima volta lo schermo, quindi una volta trascorso 800 ms viene chiamato il metodo LongTouch(). In altre parole, non voglio dover controllare per quanto tempo è trascorso ACTION_UP da ACTION_DOWN. Credo che dovrei usare un thread per il timer specificato ma non riesco a farlo funzionare. Quando si utilizza il seguente codice, il messaggio di debug viene visualizzato non appena tocco lo schermo:

 @Override 
    public boolean onTouch(View v, MotionEvent event) 
    { 
     long touchDuration = 0; 

      TouchThread touchThread = new TouchThread(); 

      if (event.getAction() == MotionEvent.ACTION_DOWN) 
      { 
       //Start timer 
       touchTime = System.currentTimeMillis(); 
       touchThread.setEvent(event); 
       touchThread.run(); 
      } 

     return true; 
    } 


    private class TouchThread extends Thread 
    { 

      public MotionEvent event = null; 

      public void setEvent(MotionEvent e) 
      { 
       event = e; 
      } 

      @Override 
      public void run() 
      { 
       long startTime = System.currentTimeMillis(); 
       long time = 0; 

       while(event.getAction() == MotionEvent.ACTION_DOWN) 
       { 
        time = System.currentTimeMillis() - startTime; 
        if(time > 800) 
        { 
         System.out.println("LOOONG CLICK!!"); 
         return; 
        } 
       } 
      } 
    } 

Qualcuno ha qualche idea? Un'altra soluzione sarebbe anche benvenuta.

Grazie.

risposta

3

Una bella opzione quando si vuole anche fare un po 'di elaborazione evento manuale è la classe GestureDetector: http://developer.android.com/reference/android/view/GestureDetector.html

Come lo uso è di fare un'istanza GestureDetector nel costruttore, implementare i metodi che mi interessano, e poi all'inizio del metodo onTouchEvent() fare qualcosa di simile:

if (gestureDetector.onTouchEvent(event)) { 
     return true; 
    } 

il che significa poi nella maggior parte dei casi quando viene rilevato un gesto che interrompe il resto della tua gestione tocco. Tuttavia, la pressione lunga è leggermente diversa perché il metodo di pressione lunga non restituisce un valore. In questo caso ho solo un booleano da qualche parte che imposto quando viene premuto a lungo che controllo in seguito il metodo di gestione degli eventi touch, se necessario.

1

Una cosa che puoi fare è impostare OnLongClickListener su SurfaceView.

mySurfaceView.setOnLongClickListener(l); 

Poi, nel tuo SurfaceView, è necessario eseguire l'override del onTouchEvent:

public boolean onTouchEvent(MotionEvent event) { 
    super.onTouchEvent(event); 
    return true; 
} 
3

E 'abbastanza facile, in realtà. Nel costruttore del vista, fare questo:

setOnLongClickListener(new View.OnLongClickListener() 
{ 
    public boolean onLongClick(View v) { 
     Log.v("debug", "LONG CLICK!"); 
     return true; 
    } 
    } 
); 

poi sovrascrivere onTouchEvent:

@Override 
    public boolean onTouchEvent(MotionEvent event) { 
     super.onTouchEvent(event); 
    } 

E il gioco è fatto;).