Domanda

Sto cercando di catturare gli eventi doppio tocco con OnTouchListener. Immagino vorrei impostare un lungo per motionEvent.ACTION_DOWN, e un diverso lungo per un secondo motionEvent.ACTION_DOWN e misurare il tempo che intercorre tra i due e poi fare qualcosa con esso. Tuttavia, sto attraversando un periodo difficile capire esattamente come affrontare questo. Sto usando corpi interruttore per raccogliere eventi multitouch, quindi preferirei non provare e riorganizzare tutto questo per implementare GestureDetector (e purtroppo non è possibile implementare sia ontouchlistener e Gesturedetector contemporaneamente). Tutte le idee sarebbe di grande aiuto:

i.setOnTouchListener(new OnTouchListener() {

        public boolean onTouch(View v, MotionEvent event) {


                  ImageView i = (ImageView) v;

                  switch (event.getAction() & MotionEvent.ACTION_MASK) {


                  case MotionEvent.ACTION_DOWN:
                      long firstTouch = System.currentTimeMillis();
                     ///how to grab the second action_down????

                     break;
È stato utile?

Soluzione

Ho affrontato questo problema in precedenza. Si tratta di utilizzare un gestore di aspettare un certo periodo di tempo di attesa per il secondo clic: Come posso creare un singolo clic evento e fare doppio clic evento quando si preme il tasto MENU?

Altri suggerimenti

Nella definizione di classe:

public class main_activity extends Activity
{
    //variable for counting two successive up-down events
   int clickCount = 0;
    //variable for storing the time of first click
   long startTime;
    //variable for calculating the total time
   long duration;
    //constant for defining the time duration between the click that can be considered as double-tap
   static final int MAX_DURATION = 500;
}

Poi, nel tuo corpo della classe:

OnTouchListener MyOnTouchListener = new OnTouchListener()
{
    @Override
    public boolean onTouch (View v, MotionEvent event)
    {
        switch(event.getAction() & MotionEvent.ACTION_MASK)
        {
        case MotionEvent.ACTION_DOWN:
            startTime = System.currentTimeMillis();
            clickCount++;
            break;
        case MotionEvent.ACTION_UP:
            long time = System.currentTimeMillis() - startTime;
            duration=  duration + time;
            if(clickCount == 2)
            {
                if(duration<= MAX_DURATION)
                {
                    Toast.makeText(captureActivity.this, "double tap",Toast.LENGTH_LONG).show();
                }
                clickCount = 0;
                duration = 0;
                break;             
            }
        }
    return true;    
    }
}

Questo è stato adattato da una risposta in: DoubleTap in android da https://stackoverflow.com/users/1395802/karn

Con la classe helper SimpleGestureListener che implementa il GestureListener e OnDoubleTapListener non avete bisogno molto da fare.

yourView.setOnTouchListener(new OnTouchListener() {
private GestureDetector gestureDetector = new GestureDetector(Test.this, new GestureDetector.SimpleOnGestureListener() {
    @Override
    public boolean onDoubleTap(MotionEvent e) {
        Log.d("TEST", "onDoubleTap");
        return super.onDoubleTap(e);
    }
    ... // implement here other callback methods like onFling, onScroll as necessary
});

@Override
public boolean onTouch(View v, MotionEvent event) {
    Log.d("TEST", "Raw event: " + event.getAction() + ", (" + event.getRawX() + ", " + event.getRawY() + ")");
    gestureDetector.onTouchEvent(event);
    return true;
}});

Questo è molto più semplice:

//variable for storing the time of first click
long startTime;
//constant for defining the time duration between the click that can be considered as double-tap
static final int MAX_DURATION = 200;

    if (event.getAction() == MotionEvent.ACTION_UP) {

        startTime = System.currentTimeMillis();             
    }
    else if (event.getAction() == MotionEvent.ACTION_DOWN) {

        if(System.currentTimeMillis() - startTime <= MAX_DURATION)
        {
            //DOUBLE TAP
        }       
    }

Ecco la mia soluzione.

E 'stato importante per me avere una veloce e chiara separazione dei 'single tap' e 'doppio tap'. Ho provato GestureDetector prima ma ha avuto risultati molto male. Forse a causa del mio uso annidata di scrollviews - chi lo sa ...

mi concentro sul MotionEvent.ACTION_UP e l'ID dell'elemento filettato. Per mantenere il primo rubinetto uso io vivo un Handler l'invio di un messaggio di ritardo (350ms), in modo che l'utente ha qualche momento di inserire il suo secondo colpetto sulla ImageView. Se l'utente collocato un secondo tap su un elemento con l'id identico prendo questo come doppio tap, rimuovere il messaggio ritardato e Rund mio codice personalizzato per 'toccare due volte'. Se l'utente messo un rubinetto su un elemento con un ID diverso prendo questo come nuovo rubinetto e creare un altro Handler per esso.

variabili globali di classe

private int tappedItemId = -1;
Handler myTapHandler;
final Context ctx = this;

Codice esempio

ImageView iv = new ImageView(getApplicationContext());
//[...]
iv.setId(i*1000+n);
iv.setOnTouchListener(new View.OnTouchListener() {

@Override
public boolean onTouch(View v, MotionEvent event) {

   switch (event.getAction()) {

      case MotionEvent.ACTION_UP: {

         //active 'tap handler' for current id?
         if(myTapHandler != null && myTapHandler.hasMessages(v.getId())) {

            // clean up (to avoid single tap msg to be send and handled)
            myTapHandler.removeMessages(tappedItemId);
            tappedItemId = -1;

            //run 'double tap' custom code
            Toast.makeText(ScrollView.this, "double tap on "+v.getId(), Toast.LENGTH_SHORT).show();

            return true;
         } else {
            tappedItemId = v.getId();
            myTapHandler = new Handler(){
               public void handleMessage(Message msg){
                  Toast.makeText(ctx, "single tap on "+ tappedItemId + " msg 'what': " + msg.what, Toast.LENGTH_SHORT).show();
               }
            };

            Message msg = Message.obtain();
            msg.what = tappedItemId;
            msg.obj = new Runnable() {
               public void run() {
                  //clean up
                  tappedItemId = -1;
               }
            };
            myTouchHandler.sendMessageDelayed(msg, 350); //350ms delay (= time to tap twice on the same element)
         }
         break;
      }
   }

   return true;
 }
});
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top