Длинное касание на поверхности View (Android) - PullRequest
7 голосов
/ 13 июля 2010

Я делаю игру на Android, и мне нужно выполнять определенные действия, когда пользователи пытаются долго нажимать на экран.К сожалению, я не нашел каких-либо методов, которые бы работали напрямую с пользовательским SurfaceView, не стесняйтесь сообщить мне, существует ли такой метод:)

Поэтому я решил попробовать реализовать обнаружение длинных прикосновений от слушателя событий onTouch.

вот мой код:

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

Это работает, но я могу определить, было ли нажатие долгим нажатием или нет, только когда пользователь перестает касаться телефона.Так что это не совсем то, что я хочу.Я бы предпочел, чтобы таймер запускался, когда пользователь впервые касается экрана, а затем по истечении 800 мс вызывается метод LongTouch ().Другими словами, я не хочу проверять, сколько времени прошло с момента ACTION_UP с момента ACTION_DOWN.Я считаю, что я должен использовать поток для указанного таймера, но я не могу заставить его работать.При использовании следующего кода сообщение отладки отображается, как только я касаюсь экрана:

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

У кого-нибудь есть идеи?Также будет приветствоваться другое решение.

Спасибо.

Ответы [ 3 ]

4 голосов
/ 06 апреля 2012

Это довольно просто, на самом деле. В конструкторе вашего представления сделайте это:

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

Затем переопределить onTouchEvent:

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

И все готово;).

3 голосов
/ 11 января 2011

Хорошим вариантом, когда вы также хотите выполнить некоторую ручную обработку событий, является класс GestureDetector: http://developer.android.com/reference/android/view/GestureDetector.html

Как я использую его, чтобы сделать экземпляр GestureDetector в конструкторе, реализовать интересующие меня методы, а затем в начале метода onTouchEvent () сделать что-то вроде:

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

Это означает, что в большинстве случаев обнаруживается жест, который прерывает обработку вашего касания. Однако длинное нажатие немного отличается, потому что метод длинного нажатия не возвращает значение. В этом случае у меня просто есть где-то логическое значение, которое я устанавливаю при длительном нажатии, и при необходимости проверяю позже в методе обработки событий касания.

2 голосов
/ 25 февраля 2011

Одна вещь, которую вы можете сделать, это установить OnLongClickListener на вашем SurfaceView.

mySurfaceView.setOnLongClickListener(l);

Затем в вашем SurfaceView вам необходимо переопределить onTouchEvent:

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