2010-07-13 6 views
5

Je fais un jeu sur Android et je dois faire certaines actions lorsque les utilisateurs tentent un appui long sur l'écran. Malheureusement, je n'ai trouvé aucune méthode qui fonctionne directement avec un SurfaceView personnalisé, n'hésitez pas à me dire si une telle méthode existe :)Long Touch sur un SurfaceView (android)

J'ai donc décidé d'essayer de mettre en œuvre une détection longue durée depuis l'écouteur d'événement onTouch.

voici mon code:

@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; 

Cela fonctionne, mais je peux détecter si la presse était un long ou non seulement lorsque l'utilisateur cesse de toucher au téléphone. Donc ce n'est pas exactement ce que je veux. Je préférerais qu'une minuterie démarre lorsque l'utilisateur touche l'écran pour la première fois, puis une fois que 800 ms se sont écoulés, la méthode LongTouch() est appelée. En d'autres termes, je ne veux pas avoir à vérifier combien de temps s'est écoulé quand ACTION_UP depuis ACTION_DOWN. Je crois que je devrais utiliser un fil pour le dit minuteur mais je ne peux pas le faire fonctionner. Lorsque vous utilisez le code suivant, le message de débogage est affiché dès que je touche l'écran:

 @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; 
        } 
       } 
      } 
    } 

Quelqu'un at-il une idée? Une autre solution serait également la bienvenue.

Merci.

Répondre

3

Une option agréable quand vous voulez aussi faire un peu de traitement des événements manuel est la classe GestureDetector: http://developer.android.com/reference/android/view/GestureDetector.html

Comment je l'utilise est de faire une instance GestureDetector dans le constructeur, mettre en œuvre les méthodes que je suis intéressé, puis au début de la méthode onTouchEvent() faire quelque chose comme:

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

ce qui signifie alors dans la plupart des cas lorsqu'un geste est détecté que avorte le reste de votre manipulation tactile. Cependant, une pression longue est un peu différente car la méthode de pression longue ne renvoie pas de valeur. Dans ce cas, j'ai juste un booléen quelque part que je mets quand une pression longue est déclenchée que je vérifie plus tard dans la méthode de gestion des événements tactiles si nécessaire.

1

Une chose que vous pouvez faire est de définir OnLongClickListener sur votre SurfaceView.

mySurfaceView.setOnLongClickListener(l); 

Ensuite, dans votre SurfaceView, vous devez remplacer le onTouchEvent:

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

Il est assez facile, en fait. Dans le constructeur de votre point de vue, faites ceci:

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

Puis outrepasser onTouchEvent:

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

Et vous définissez;).

Questions connexes