How to make onTouch works like onTap in Android?

夙愿已清 提交于 2020-01-07 02:44:11

问题


I've implemented an OnTouchListener in my MapActivity and of course I had to override the onTouch() method.

I want it to fire only when I tap on the map - otherwise I can't even move the map.

Here's my onTouch method:

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

    if (e.getAction() == MotionEvent.ACTION_DOWN) {

      // SOME ACTIONS ...

    }
    return true;
}

回答1:


use:

e.getAction() == MotionEvent.ACTION_UP

and:

e.getAction() == MotionEvent.ACTION_MOVE

if there was and ACTION_UP event after and ACTION_DOWN, and no ACTION_MOVE between, its a tap

UPDATED:

private int mLastMotionEventAction = MotionEvent.ACTION_UP;

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

    if (e.getAction() == MotionEvent.ACTION_DOWN) {


      // SOME DOWN ACTIONS ...

    } else if (e.getAction() == MotionEvent.ACTION_MOVE) {

      // SOME MOVE ACTIONS ...

    } else if (e.getAction() == MotionEvent.ACTION_UP) {
       if (mLastMotionEventAction == MotionEvent.ACTION_DOWN){

         // SOME TAP ACTIONS ...

       }
    }
    mLastMotionEventAction = e.getAction();
    return true;
}

Another option (for sensitive devices):

    private long mLastDownEventTime = 0;

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

        if (e.getAction() == MotionEvent.ACTION_DOWN) {
           mLastDownEventTime = System.currentTimeMillis();

          // SOME DOWN ACTIONS ...

        } else if (e.getAction() == MotionEvent.ACTION_MOVE) {

          // SOME MOVE ACTIONS ...

        } else if (e.getAction() == MotionEvent.ACTION_UP) {
           if (System.currentTimeMillis() - mLastDownEventTime < 500){

             // SOME TAP ACTIONS ...

           }
        }

        return true;
    }

This will trigger tap action only if 200ms or less have passed since last down press. Of course, you can change the timing for best UX.




回答2:


You must return false if you want to pass the event along to the Map as well. Otherwise, as you describe, the map will not react to touch gestures. This is because, returning true means that you consumed the event.




回答3:


I know this is an old question, but the right way to do it is using getScaledTouchSlop() which returns the distance in pixels a touch can wander before we think the user is scrolling.

Implement it like this in your onTouch method:

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

        int mSwipeSlop = ViewConfiguration.get(context).
                    getScaledTouchSlop();
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            // DO
            break;
        case MotionEvent.ACTION_CANCEL:
            // DO
            break;
        case MotionEvent.ACTION_MOVE:
            {
                float x = event.getX() + v.getTranslationX();
                float deltaX = x - mDownX;
                float deltaXAbs = Math.abs(deltaX);
                float y = event.getY() + v.getTranslationY();
                float deltaY = Y - mDownY;
                float deltaYAbs = Math.abs(deltaY);
                float absDist = Math.sqrt(Math.pow(deltaXAbs, 2) + Math.pow(deltaXAbs, 2));
                if (!mSwiping) {
                    if (absDist > mSwipeSlop) {
                        mSwiping = true;
                    }
                }
            break;
        case MotionEvent.ACTION_UP:
            {
                if (mSwiping) {
                    // DO MOVE ACTIONS
                }
                else {
               // DO TAP ACTIONS
                }
            }
            break;
        default: 
            return false;
        }
        return true;
    };

developer page: http://developer.android.com/reference/android/view/ViewConfiguration.html#getScaledTouchSlop()



来源:https://stackoverflow.com/questions/12618045/how-to-make-ontouch-works-like-ontap-in-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!