简体   繁体   English

检测视图上的滑动手势和触摸事件

[英]Detect swipe gestures and touch events on a view

Android Studio, Java安卓工作室,Java

Is there a way to detect touch down, touch release, and swipe gestures, on a single view ?有没有办法在单个视图上检测触摸、触摸释放和滑动手势? I have a button and I need to be able to listen to all of these on it.我有一个按钮,我需要能够听到所有这些。

I'm looking for a solution where the listeners/detectors end up calling these methods so I easily can work with them:我正在寻找一种解决方案,让侦听器/检测器最终调用这些方法,以便我可以轻松地使用它们:

public void buttonPressedDown() {

}

public void buttonReleased() {

}

public void swipeUp() {

}

public void swipeRight() {

}

public void swipeDown() {

}

public void swipeLeft() {

}

This is easy to accomplish in xcode when developing ios apps, but I can't seem to find a way to do it for android.在开发 ios 应用程序时,这很容易在 xcode 中完成,但我似乎无法找到一种方法来为 android 做到这一点。

Extra info: This is what I've tried:额外信息:这是我尝试过的:

    timerButton.setOnTouchListener(new View.OnTouchListener() { //Detecting a press down
        @Override
        public boolean onTouch(View v, MotionEvent event) {

            timerDown();

            return false;
        }
    });

    timerButton.setOnTouchListener(new OnSwipeTouchListener(timerActivity.this) {//Detecting swipes

        public void onSwipeTop() {

            showStats();

        }

        public void onSwipeBottom() {

            showType();

        }

        public void onSwipeRight() {

            showMenu();

        }

        public void onSwipeLeft() {

            showTimes();

        }

    });


    .
    .
    .


    public void timerButtonPressed(View view) {//Detecting press releases
        timerUp();
    }

This seemed like what I was looking for, except it didn't work.这似乎是我正在寻找的东西,但它不起作用。 When setting two onTouchListeners on the same view, only one of the listeners were being called.在同一个视图上设置两个 onTouchListeners 时,只有一个监听器被调用。 Either only the swipe detections worked, or only the press detections, when I tested it.当我测试它时,要么只有滑动检测有效,要么只有按压检测有效。

Help!?帮助!?

Edit: I've tried this:编辑:我试过这个:

OnSwipeTouchListener.java OnSwipeTouchListener.java

public class OnSwipeTouchListener implements View.OnTouchListener {

    private final GestureDetector gestureDetector;

    public OnSwipeTouchListener(Context context) {
        gestureDetector = new GestureDetector(context, new GestureListener());
    }

    public void onSwipeLeft() {
    }

    public void onSwipeRight() {
    }

    public boolean onTouch(View v, MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
    }

    private final class GestureListener extends GestureDetector.SimpleOnGestureListener {

        private static final int SWIPE_DISTANCE_THRESHOLD = 100;
        private static final int SWIPE_VELOCITY_THRESHOLD = 100;

        @Override
        public boolean onDown(MotionEvent e) {
            return true;
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            float distanceX = e2.getX() - e1.getX();
            float distanceY = e2.getY() - e1.getY();
            if (Math.abs(distanceX) > Math.abs(distanceY) && Math.abs(distanceX) > SWIPE_DISTANCE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                if (distanceX > 0)
                    onSwipeRight();
                else
                    onSwipeLeft();
                return true;
            }
            return false;
        }
    }
}

And in my activity:在我的活动中:

timerButton.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {

            OnSwipeTouchListener onSwipeTouchListener = new OnSwipeTouchListener(timerActivity.this);
            boolean result = onSwipeTouchListener.onTouch(v, event);
            // check if swipe was detected:
            if (result) return true;

            // Otherwise, detect other types of motion event
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    // touch down

                    timerDown();

                    break;
                case MotionEvent.ACTION_UP:
                    // touch released

                    timerUp();

                    break;
            }

            return false;
        }
    });

But how would I detect the swipes from here?但是我如何从这里检测到滑动? Also when I run the application it doesn't even detect touches anymore.此外,当我运行该应用程序时,它甚至不再检测到触摸。

I also tried this in my activity:我也在我的活动中尝试过这个:

timerButton.setOnTouchListener(new OnSwipeTouchListener(timerActivity.this) {

        public void onSwipeLeft() {
            Log.i("LEFT", "LEFT");
        }

        public void onSwipeRight() {
            Log.i("RIGHT", "RIGHT");
        }

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

            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    // touch down

                    timerDown();

                    break;
                case MotionEvent.ACTION_UP:
                    // touch released

                    timerUp();

                    break;
            }

            return false;
        }
    });

Now it detects touches but won't detect swipes.现在它检测到触摸但不会检测滑动。 If I remove the @override onTouch method above, but still have the onSwipe methods, then the swipes are detected.如果我删除了上面的@override onTouch 方法,但仍然有 onSwipe 方法,那么就会检测到滑动。 How is this so complicated?这怎么这么复杂? Why won't it detect both swipes and touches, and how do I solve it?为什么它不能同时检测滑动和触摸,我该如何解决?

I found a solution.我找到了解决方案。

In OnSwipeTouchListener.java:在 OnSwipeTouchListener.java 中:

public class OnSwipeTouchListener implements View.OnTouchListener {

private final GestureDetector gestureDetector;

public OnSwipeTouchListener(Context context) {
    gestureDetector = new GestureDetector(context, new GestureListener());
}

public void onSwipeLeft() {
}

public void onSwipeRight() {
}

public void onSwipeBottom() {
}

public void onSwipeTop() {
}

public void onDownTouch() {

}

public boolean onTouch(View v, MotionEvent event) {
    return gestureDetector.onTouchEvent(event);
}

private final class GestureListener extends GestureDetector.SimpleOnGestureListener {

    private static final int SWIPE_DISTANCE_THRESHOLD = 100;
    private static final int SWIPE_VELOCITY_THRESHOLD = 100;

    @Override
    public boolean onDown(MotionEvent e) {
        onDownTouch();
        return false;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        boolean result = false;
        try {
            float diffY = e2.getY() - e1.getY();
            float diffX = e2.getX() - e1.getX();
            if (Math.abs(diffX) > Math.abs(diffY)) {
                if (Math.abs(diffX) > SWIPE_DISTANCE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffX > 0) {
                        onSwipeRight();
                    } else {
                        onSwipeLeft();
                    }
                    result = true;
                }
            }
            else if (Math.abs(diffY) > SWIPE_DISTANCE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                if (diffY > 0) {
                    onSwipeBottom();
                } else {
                    onSwipeTop();
                }
                result = true;
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return result;
    }
}

} }

And in activity:在活动中:

To detect button release press: (on click)检测按钮释放按下:(点击)

public void timerButtonPressed(View view) {

}

To detect swipes and down press:要检测滑动和向下按:

timerButton.setOnTouchListener(new OnSwipeTouchListener(timerActivity.this) {

        public void onSwipeLeft() {

        }

        public void onSwipeRight() {

        }

        public void onSwipeBottom() {

        }

        public void onSwipeTop() {

        }

        public void onDownTouch() {

        }
    });

Calling setOnTouchListener the second time overwrites your previous listener.第二次调用setOnTouchListener覆盖之前的监听器。 You can detect both touches and gestures by:您可以通过以下方式检测触摸和手势:

timerButton.setOnTouchListener(new View.OnTouchListener() { 
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // deliver motion event to your swipe listener
            boolean result = mySwipeListener.onTouch(event);
            // check if swipe was detected:
            if (result) return true;

            // Otherwise, detect other types of motion event
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    // touch down
                    break;
                case MotionEvent.ACTION_UP:
                    // touch released
                    break;
                // etc... see this link for more motion events https://developer.android.com/reference/android/view/MotionEvent
            }

            return false;
        }
    });

Here's an example on implementing on swipe listener: Android: How to handle right to left swipe gestures这是在滑动监听器上实现的示例: Android:如何处理从右向左滑动手势

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM