如何在内部视图接受onSingleTapUp(),同时在外部视图接受onFling()?

5
我有一个覆盖整个屏幕的视图(称为ParentView),和一个只覆盖部分屏幕的子视图ChildView。我想让ChildView响应onSingleTapUp()事件,而让ParentView响应onFling()事件。我尝试在ChildView上附加一个SimpleOnGestureListener监听器,并在ParentView上附加另一个SimpleOnGestureListener监听器来实现这个目标。
为了接收来自ChildViewonSingleTapUp()事件,其监听器的onDown()方法必须返回true。但一旦我这样做了,与ParentView相关联的监听器就无法再捕获任何运动事件,因为这些事件已被ChildView的监听器占用。即使ChildViewonFling()方法返回false,这些事件也无法流向ParentView的监听器。 如何才能让父视图的监听器捕获滑动手势,同时让子视图的监听器捕获点击手势? 我认为不需要任何源代码来解释这种情况,但是这里是设置我的ChildView监听器的代码片段。
ChildView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        return singleTapGestureDetector.onTouchEvent(motionEvent);
    }
});

一种解决方法可能是让ParentViewChildView的监听器都处理onFling(),而只有ChildView的监听器处理onSingleTapUp()。但在这种情况下,快速滑动不会跨越ChildView(比如从子视图之外开始,然后在子视图内结束)。

1个回答

2

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

正如我在问题中描述的那样,问题在于手势监听器的工作方式。为了让子视图捕获onSingleTapUp()事件,你需要在onDown()上返回true。但是一旦你这样做了,在子视图的onTouch()声明不再关注该事件后,随后的一系列事件甚至不会传递到父视图。如果你在子视图的onTouch()中强制调用父视图的onTouch(),并且手势检测器返回false,则父视图的onFling()将被调用,但第一个MouseEvent参数将为空,因为它已经被子视图的onTouch()消耗掉了。

我可能错过了什么,因为这似乎是非常基本的手势检测场景。无论如何,我找不到合理的方法来解决这个问题。

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

子视图和父视图都有这一行代码:

view.setOnTouchListener(TouchListenerService.Instance());

而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

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


这对我很有效,我尝试了其他方法但都没有成功,比如使用FrameLayout - 那里也有同样的问题。接受这个答案 - 希望它能帮助未来的其他人,或者有人会注意到更好的方法来解决它。 - kennethc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接