Android 中的 MotionEvent.ACTION_DOWN 过于敏感。即使只是触摸屏幕片刻,也会收到此事件

MotionEvent.ACTION_DOWN in Android is too sensitive. This event is received even if the screen is simply touched for a moment

我有一个布局(A table 布局)。每当用户执行 "down" 手势时,需要调用特定函数。但是,ontouchlistener 会立即捕获事件,而不是等到用户执行正确的 "pull down" 手势。

我的代码是:

homePageTableLayout.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View view, MotionEvent event) {
                if ((event.getAction() == MotionEvent.ACTION_DOWN)) {
                    startSyncData();
                }
                return true;
            }
        });

目前,正在发生的是立即调用 startSyncData() 函数。 最终结果应该有点类似于 android 的常用 "pulltorefresh" 库,但在这个用例中,我不必更新视图。我只需要 post 一些数据到服务器。 我无法使用 "pulltorefresh" 库,因为它不支持 "pulling" 和 table 布局。我尝试将 table 布局放在滚动视图中,但这只会破坏 UI.

没那么容易。它工作正常,因为你正在捕捉 MotionEvent.ACTION_DOWN。这并不意味着像向下滑动这样的手势,它意味着用户触摸了屏幕(手指向下,触摸或手势刚刚开始)。现在你需要抓住 MotionEvent.ACTION_UP(手指向上,手势或触摸到此结束)并决定是否有你需要的手势。 http://developer.android.com/training/gestures/detector.html
http://developer.android.com/training/gestures/index.html

您可以尝试在 ACTION_MOVEACTION_UP 中执行此操作 - 如果您需要仅通过向下滑动手势来完成,这应该会有所帮助,介绍四个全局 floatsx, y, x1, y1,然后在 ACTION_DOWN:

x = event.getX();
y = event.getY();

ACTION_MOVEACTION_UP:

x1 = event.getX();
y1 = event.getY();

然后在 ACTION_UP:

if (y1 > y) {        //pointer moved down (y = 0 is at the top of the screen)
    startSyncData(); 
}

MotionEvent.ACTION_MOVE 反复被调用。因此,如果您希望在移动一定距离后 startSyncData() 到 运行,请在 运行 启用该方法之前计算您希望用户移动多少。

关键是ACTION_DOWN不是在屏幕上向下移动,而是用户按下屏幕。

homePageTableLayout.setOnTouchListener(new View.OnTouchListener() {
        public boolean onTouch(View view, MotionEvent event) {
            if ((event.getAction() == MotionEvent.ACTION_DOWN)) {
                startFlg = 1;
            } else if ((event.getAction() == MotionEvent.ACTION_MOVE)) {
                if (startFlg==1){
                    // Calculate distance moved by using event.getRawX() and event.getRawX() and THEN run your method
                    startSyncData();
                }
            }
            return true;
        }
    });