在可点击的项上检测快速滑动手势

25

设想一个拥有4个按钮的布局

 _______________________________
|              |                |
|      A       |       B        |
|______________|________________|
|              |                |
|      C       |       D        |
|______________|________________|

我想检测整个布局中的fling手势,但当fling在按钮上开始时无法检测到。

我正在使用:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    gesturedetector= new GestureDetector(this, this);

    findViewById(R.id.touchContainer).setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Log.e("","TouchEvent");
            return gesturedetector.onTouchEvent(event);
        }
    });
}

如果没有可点击的项,则它能正常工作,但如果 fling(快速滑动)开始于可点击的项上,则失败。

我该如何解决这个问题?愿意出 50 分赏金求得完整可行的答案。


2
将“为完整的有效答案提供50积分作为奖励”称为“开放赏金”,这是StackExchange网站长期实施的概念。请参见此FAQ部分:http://stackoverflow.com/faq#bounty - Paul Sasik
你需要在这个问题上设置赏金,并且可能需要提供超过50声望的奖励。为什么?因为我认为答案很可能是一个自定义的滑动检测器,可以跨多个控件工作... - Paul Sasik
页面上显示“2天内有赏金的问题”,所以我一有机会就会开启悬赏并将其分配给一个答案。当然,如果没有简单的答案,我会支付更多,这不是问题。 - Addev
其实,我有一个想法...虽然我对Android UI不是很熟悉,但在其他平台上,我会在按钮上覆盖一个透明面板。该面板将处理所有事件,其中滑动将被处理一种方式,而点击将被转换为网格中“下方”按钮的按钮按下。 - Paul Sasik
@Addev:你是如何解决这个问题的?请分享代码。谢谢。 - user1090751
1个回答

28

我达到这个目的的一种方法是覆盖以下方法:

public boolean onInterceptTouchEvent(MotionEvent event){
    super.onInterceptTouchEvent(event);
    ...
您可以在布局容器中重写此方法(例如,ViewGroup或用于包含按钮的任何其他容器),并继续从中返回false以'拦截'被子View(即您的按钮)使用的触摸事件。在覆盖的方法内,您可以使用MotionEvent调用您的手势检测器对象。该方法还能'看到'针对ViewGroup本身的事件,这意味着 - 如果我记得正确 - 您只需要在该方法内部调用手势检测器,并且通过这样做,手势检测器将'看到'所有事件,无论它们是否在按钮上方。因此,如果您从按钮上方开始拖动手指,然后在布局背景上的某个点结束,则手势检测器应该看到整个滑动操作。您不需要从布局自己的onTouchEvent()中提供事件给手势检测器,因为它已经看到了它们。
第二种方式:
我刚刚查看了我的项目,发现我切换到了另一种方法。实际上,我设计了所有的子View,使得父Activity(或包含的ViewGroup)可以向所有这些子View注册相同的手势检测器对象(我的每个特殊View都有一个名为registerGestureDetector()的方法)。然后,在我子View中覆盖的'onTouchEvent()'中,将MotionEvent传递给已向该View注册的手势检测器。换句话说,父ViewGroup布局和所有子View只需共享相同的手势检测器。
我意识到这可能听起来有点麻烦,而且不必要,因为它可以使用onInterceptTouchEvent()实现,但是我的应用程序涉及一些非常复杂的规则,关于如何响应触摸事件和手势,它允许我应用一些我特定应用程序所需的附加逻辑。但是,我使用的这两种方法都实现了相同的基本目标:将针对各种ViewMotionEvent引导到同一个手势检测器对象中。

非常感谢您的回答,只是在测试,但两个答案似乎都可以工作!=)尽快给予悬赏。 - Addev
据说,如果在父级“ViewGroup”上设置为true,则splitMotionEvents应该自动启用此功能。但实际上并没有发生。也许是一个bug?虽然文档中的措辞含糊不清,例如“可能”,并且没有指定当触摸事件同时发生在两个视图上(即UP和DOWN)时会发生什么。 - leRobot
我在我的代码中使用自定义日历,并希望使用fling滑动日历。但是在CalendarView上使用onInterceptTouchEvent时无法正常工作。你能分享一下你的onInterceptTouchEvent代码吗? - Rakesh
@Trevor:有使用第一种方法的示例或教程链接吗?谢谢。 - user1090751

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