Как перехватить события двойного нажатия в Android с помощью OnTouchListener - PullRequest
9 голосов
/ 06 сентября 2011

Я пытаюсь перехватить события двойного нажатия, используя OnTouchListener.Я полагаю, что я установил бы long для motionEvent.ACTION_DOWN, а другой long для второго motionEvent.ACTION_DOWN и измерил время между ними и затем что-то сделал с этим.Однако мне трудно понять, как именно к этому подойти.Я использую переключатели для захвата событий мультитач, поэтому я бы не стал пытаться переоборудовать все это для реализации GestureDetector (и, к сожалению, невозможно одновременно реализовать ontouchlistener и Gesturedetector).Любые идеи очень помогли бы:

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;

Ответы [ 5 ]

12 голосов
/ 11 апреля 2013

В вашем определении класса:

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

Тогда в теле вашего класса:

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

Это было адаптировано из ответа в: DoubleTap в Android отhttps://stackoverflow.com/users/1395802/karn

8 голосов
/ 13 ноября 2015

С вспомогательным классом SimpleGestureListener, который реализует GestureListener и OnDoubleTapListener, вам не нужно много делать.

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;
}});
6 голосов
/ 30 июня 2014

Это намного проще:

//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
        }       
    }
2 голосов
/ 06 сентября 2011

Я обращался к этой проблеме ранее.Он включает использование обработчика для ожидания определенного количества времени ожидания второго щелчка: Как создать событие одиночного щелчка и двойного щелчка при нажатии кнопки меню?

0 голосов
/ 20 сентября 2014

Вот мое решение.

Для меня было важно иметь быстрое и четкое разделение «одно касание» и «двойное касание».Сначала я попробовал GestureDetector, но результаты были очень плохими.Возможно, результат моего вложенного использования scrollviews - кто знает ...

Я сосредотачиваюсь на MotionEvent.ACTION_UP и идентификаторе подключенного элемента.Чтобы сохранить первое нажатие, я использую Handler, отправляющее отложенное сообщение (350 мс), чтобы у пользователя было некоторое время, чтобы поместить второе нажатие на ImageView.Если пользователь нажал второй элемент на элемент с идентичным идентификатором, я бы назвал это двойным нажатием, удалите отложенное сообщение и присвойте мой пользовательский код «двойному касанию».Если пользователь нажал на элемент с другим идентификатором, я бы использовал его как новый и создал для него еще один Handler.

Глобальные переменные класса

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

Пример кода

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;
 }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...