Android 如果用户将手指从按钮上移开,则按“取消”按钮

Android 如果用户将手指从按钮上移开,则按“取消”按钮,android,button,ontouchlistener,Android,Button,Ontouchlistener,这是我的标准按钮,点击这里: b.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) { b.setPressed(tru

这是我的标准按钮,点击这里:

b.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {
            b.setPressed(true);
        }
        if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP) {
            b.setPressed(false);
            // Do the button action stuff here
        }
        return true;
    }
});
当用户按下按钮时,我将按钮设置为“按下”。当用户抬起手指时,我将按钮设置为“未按下”,然后执行按钮应该执行的操作

这一切都很好,除了用户按下按钮,然后在继续保持手指向下的同时,将手指移出按钮区域的情况。当手指被提起时,动作就开始了。我想将此行为作为按钮按下的“取消”。因此,一旦按下的手指移出按钮区域,我想
b.setPressed(false)
我已尝试使用
MotionEvent.ACTION\u CANCEL
MotionEvent.ACTION\u OUTSIDE
(如建议的那样),但我肯定遗漏了一些内容,因为它们不起作用


从中可以看出,这可以通过
event.getX()
event.getY()
完成。如果getX()为负数,你就离开了左边,如果getY()为负数,你就离开了顶部,但是要想知道你是离开了右边还是底部,我必须计算出按钮的大小,然后。。。必须有一个更简单的方法。有吗?

你回答对了。使用
getWidth()
getHeight()
获取宽度和高度,并检查x或y是否更大

ACTION\u CANCEL
不起作用,因为当父视图控制触摸事件时会生成
CANCEL
,就像滚动时的
ListView
一样


外部操作\u
仅在您请求的某些异常情况下发生。因为没有人发布任何代码,所以它不会仅为正常的
移动
向上
而生成,这里有一个。布尔值用于指示应在何时执行相应的操作

处理
MotionEvent.ACTION\u MOVE
事件以检查手指是否移出边界。如果是,
b.setPressed(假),布尔值用于指示下一次不应触发动作,即取消按钮单击

MotionEvent.ACTION\u UP
中,调用
b.setPressed(false)仅当布尔值不表示跳过时(如上所述)。如果是这样,则反转布尔值,以便下次执行按钮操作

private Boolean notNow = false;
private Rect rect;    // Variable rect to hold the bounds of the view

b.setOnTouchListener(new OnTouchListener(){
    @Override
    public boolean onTouch(View v, MotionEvent event){
        if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN){
            b.setPressed(true);
            rect = new Rect(v.Left, v.Top, v.Right, v.Bottom);
        }
        if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP){
            if (!notNow){
                b.setPressed(false);
            }
            else //button press canceled
                notNow = false;  
        }
        if((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_MOVE){
            if(!notNow)
                if (!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())){ 
                    // finger moved out of bounds
                    b.setPressed(false);
                    notNow = true; //cancel button press the next time
                }
        }

        return true;
});

非常感谢。getX()和get(y)不会是一个很大的工作量,但是我很惊讶没有“内置”的方法来实现这一点,因为它看起来像是一个非常明显的按钮特性。多亏了投反对票的人。似乎描述了一个类似的情况,行动显然奏效了。也许我不明白那里发生了什么。当父视图(如滚动视图或列表视图)拥有触摸事件的所有权时(如滚动视图认为您正在滚动时),会生成ACTION\u CANCEL。除非你有类似的观点,否则在这里你不会看到一个动作被取消。好吧,我不得不承认,没有一个优雅的方式来做这件事。对我来说仍然很奇怪,但我想就是这样。