如何在内部视图上接受 onSingleTapUp() 而在外部视图上接受 onFling() ?

ken*_*thc 5 android gesture ontouchlistener

我有一个覆盖整个屏幕的视图(比方说ParentView),以及ChildView仅覆盖其中一部分的子内部视图。我要做出ChildView回应onSingleTapUp(),同时ParentView回应onFling()。我试图通过附加一个SimpleOnGestureListenerChildView一个SimpleOnGestureListener来做到这一点ParentView

要接受onSingleTapUp()from ChildView,其侦听器onDown()必须返回 true。但是一旦我这样做了,绑定的侦听器ParentView就不会再听到任何运动事件,因为它是由 的ChildView侦听器获取的。即使ChildView'sonFling()返回 false,事件也不会流到ParentView's 侦听器。

如何使父视图的侦听器捕获 fling 手势,同时子视图的侦听器捕获点击手势?

我认为不需要任何源代码来解释这种情况,但这里有一个设置我的ChildView监听器的片段。

ChildView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        return singleTapGestureDetector.onTouchEvent(motionEvent);
    }
});
Run Code Online (Sandbox Code Playgroud)

一种解决方法可能是同时让ParentViewChildView的侦听器处理onFling()while onlyChildView的侦听器句柄onSingleTapUp(),但在这种情况下,fling 将无法跨过发生ChildView(例如从子项外部开始,然后在子项内结束),我相信。

ken*_*thc 2

我不喜欢我的解决方案,但我找到了一种方法来做到这一点。希望其他人将来能发布更好的答案,或者至少我的解决方法对其他人有用。

正如我在问题中所描述的,问题在于手势侦听器的工作原理。对于要捕获onSingleTapUp()事件的子视图,您可以在 上返回 true onDown()onTouch()但是一旦你这样做了,即使你的子视图声明它不再对事件感兴趣,后续的一系列事件也不会转到父视图。onTouch()如果您在子视图的手势检测器返回 false 时强制调用父视图onTouch(),那么父视图的 onFling() 将被调用,但第一个MouseEvent参数将为 NULL,因为它被子视图的onTouch().

我一定错过了一些东西,因为这似乎是非常基本的手势检测场景。无论如何,我找不到一种合理的方法来做到这一点。

因此,我的解决方法是将 TouchListenerService 设置为单例。

子视图和父视图都有这一行

view.setOnTouchListener(TouchListenerService.Instance());
Run Code Online (Sandbox Code Playgroud)

TouchListenerService 的启动方式如下:

public class TouchListenerService
    extends GestureDetector.SimpleOnGestureListener
    implements View.OnTouchListener {

    // some code to implement singleton

    public SingleTapUpHandler SingleTapUpHandler;
    public FlingHandler FlingHandler;

    private View _touchingView;

    GestureDetector gestureDetector;

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (gestureDetector == null)
            gestureDetector =  new GestureDetector(_touchListenerService);

        _touchingView = view;
        boolean result = gestureDetector.onTouchEvent(motionEvent);
        _touchingView = null;
        return result;
    }
    // and some more code
Run Code Online (Sandbox Code Playgroud)

由于它是相同的事件处理程序,父视图onFling()成功捕获事件,而子视图可以设置SingleTapUpHandler处理点击事件。