Определите одно касание и одно касание на Android - PullRequest
0 голосов
/ 23 февраля 2012

Я разрабатываю игру с двумя функциями, одна называется singleClick (), а другая moveClick (float dx, float dy)

singleClick () вызывается из MotionEvent.ACTION_UP

moveClick () вызывается из MotionEvent.ACTION_MOVE (где dx = x- previousX)

Моя проблема: если я пытаюсь выполнить действие перемещения пальцем, также вызывается один щелчок. Противоположно также то же самое, когда я щелкаю что-то одним пальцем, вызывается moveClick ().

Я могу обработать функцию moveClick (), вызываемую одним щелчком, но вызовы singleClick (), когда игрок движется, действительно портят мои элементы управления игрой.

Как я могу узнать, что есть что?

Ответы [ 3 ]

0 голосов
/ 23 февраля 2012

Ну, если вы не хотите вызывать singleClick (), когда игрок перемещается туда, куда он касается, то вы не можете вызывать singleClick из ACTION_UP, потому что ACTION_UP вызывается каждый раз. Может быть, добавить флаг, который отслеживает, является ли это событие перемещения. Если общее евклидово расстояние, sqrt (dx ^ 2 + dy ^ 2)> threshold, то поменяйте флаг isMove на true. Если общее расстояние меньше этого порога, вызовите singleClick () в ACTION_UP.

Вы также можете подумать о сроках, как долго длится событие касания, или об абсолютном абсолютном расстоянии (то есть, если кто-то нарисует круг и вернется к первой точке, мой предыдущий метод будет регистрироваться как один щелчок). Подумайте, как вы хотите, чтобы флаг работал.

0 голосов
/ 24 февраля 2012

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

long millisLastTouch=0, millisDif,millisStartTouch=0;
final long minMillisSm = 200, minMillisBig = 300;
boolean isMove = true;


public void run(){//my main thread/loop
    .....
        millisDif = System.currentTimeMillis() - millisLastTouch;
        if (!isMove && millisDif>minMillisBig)  {
            G.currentScreen.singleClick(mPreviousX,mPreviousY);
            isMove = true;//to prevent multiple single clicks
        }
   .....
   }//end of main loop




public boolean onTouchEvent(MotionEvent e) {
    float x = e.getX();     float y = e.getY();         
    switch (e.getAction()) {
    case MotionEvent.ACTION_DOWN:       {       }//do nothing

    case MotionEvent.ACTION_UP:{
        mPreviousX = x; mPreviousY = y;     }

    case MotionEvent.ACTION_MOVE:{
        boolean newAction;
        millisDif = System.currentTimeMillis() -  millisLastTouch;
        if (millisDif> minMillisSm) {
            newAction = true;
            millisStartTouch = System.currentTimeMillis();
        } 
        else newAction = false;

        millisLastTouch = System.currentTimeMillis();   

        millisDif = System.currentTimeMillis() -  millisStartTouch;
        if (newAction == false && millisDif > minMillisSm){
            float dx = x - mPreviousX;  float dy = y - mPreviousY;
            G.currentScreen.clickMove(x,y,dx,dy);
            isMove = true;
        }
        else isMove = false;        

        mPreviousX = x; mPreviousY = y;
    }   
    }//switch
    return true;
}//onTouchEvent

Это только время, а не расстояние. Если пользователь дотронется до экрана достаточно времени, он будет переведен как действие перемещения. В противном случае он запоминает позиции x и y и вызывает singleClick () из основного потока

0 голосов
/ 23 февраля 2012

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

...