【问题标题】:Identify single touch vs move touch on Android在 Android 上识别单点触控与移动触控
【发布时间】:2012-02-23 18:20:40
【问题描述】:

我正在开发一个具有 2 个函数的游戏,一个称为 singleClick(),另一个称为 moveClick(float dx, float dy)

singleClick() 从 MotionEvent.ACTION_UP 调用

moveClick() 从 MotionEvent.ACTION_MOVE 调用(其中 dx = x-previousX)

我的问题:如果我用手指尝试移动动作,也会调用单击。反之亦然,当我用手指单击某物时,会调用 moveClick()。

我可以处理单击时调用的 moveClick(),但是当玩家移动时调用 singleClick() 确实搞砸了我的游戏控制。

我怎么知道哪个是哪个??

【问题讨论】:

    标签: android controls touch


    【解决方案1】:

    我认为这可能与消耗触摸事件有关。在您的 onclick 侦听器中,请记住,如果您返回 true 表示您已使用该事件,如果您返回 false 该事件将继续通过并触发下一个侦听器。

    【讨论】:

      【解决方案2】:

      如果你不想在玩家移动到他触摸的地方时调用 singleClick(),那么你不能从 ACTION_UP 调用 singleClick,因为每次都会调用 ACTION_UP。也许添加一个标志来跟踪它是否是一个移动事件。如果总欧式距离 sqrt(dx^2 + dy^2) > 阈值,则将标志 isMove 更改为 true。如果总距离小于该阈值,则在 ACTION_UP 中调用 singleClick()。

      您可能还想考虑触摸事件的时间长度或总绝对距离(即,如果有人画了一个圆圈并返回到第一个点,我之前的方法将注册为单击)。考虑一下您希望标志如何工作。

      【讨论】:

        【解决方案3】:

        我希望有一个优雅的解决方案,也许是 android 开发内置的东西。但我想没有,所以我接受了 Benoir 的建议并编写了这个非常不优雅的代码(这似乎工作得很好)

        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()

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多