ScrollView 中的 View 中的 OnTouchListener

OnTouchListener in View that is inside ScrollView

我在 ScrollView 中有一个视图。只要用户按住该视图,我想每 80 毫秒调用一次方法。这是我实现的:

final Runnable vibrate = new Runnable() {
    public void run() {
        vibrate();
    }
};

theView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
            final ScheduledFuture<?> vibrateHandle =
                    scheduler.scheduleAtFixedRate(vibrate, 0, 80, MILLISECONDS);
            vibrateHanlers.add(vibrateHandle);
            return true;
        }
        if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL
                || motionEvent.getAction() == MotionEvent.ACTION_UP) {
            clearAllScheduledFutures();
            return false;
        }
        return true;
    }
});

问题是,ACTION_CANCEL 是为手指的最小移动而调用的。我知道那是因为 ViewScrollView 里面,但我不确定我在这里有什么选择。我是否创建自定义 ScrollView,并尝试查找是否触摸了所需的视图并禁用 ScrollView 的触摸事件?或者,为小的移动阈值禁用 SrollView 的触摸事件?或者别的什么?

您能否尝试在 ActionUp 事件中 return true 而不是 false,这样该事件被视为已消耗

if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL
                || motionEvent.getAction() == MotionEvent.ACTION_UP) {
            clearAllScheduledFutures();
            return true;
        }

这是我修复它的方法。

我创建了自定义 ScrollView:

public class MainScrollView extends ScrollView {
    private boolean shouldStopInterceptingTouchEvent = false;

    public void setShouldStopInterceptingTouchEvent(boolean shouldStopInterceptingTouchEvent) {
        this.shouldStopInterceptingTouchEvent = shouldStopInterceptingTouchEvent;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (shouldStopInterceptingTouchEvent)
            return false;
        else
            return super.onInterceptTouchEvent(ev);
    }
}

并且在 onTouchEvent 中:

theView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
            svMain.setShouldStopInterceptingTouchEvent(true);
            final ScheduledFuture<?> vibrateHandle =
                    scheduler.scheduleAtFixedRate(vibrate, 0, 80, MILLISECONDS);
            vibrateHanlers.add(vibrateHandle);
            return true;
        }
        if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL
                || motionEvent.getAction() == MotionEvent.ACTION_UP) {
            svMain.setShouldStopInterceptingTouchEvent(false);
            clearAllScheduledFutures();
            return false;
        }
        return true;
    }
});

所以,我决定在 ViewonTouchListener 中决定何时停止拦截 touchEvent