如果用户将手指移开按钮,则按下取消按钮

时间:2014-07-12 07:05:22

标签: android button ontouchlistener

这是我非常标准的onTouchListener按钮:

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;
    }
});

当用户按下按钮时,我将按钮设置为"按下"。当用户抬起手指时,我将按钮设置为"未按下"然后按下按钮应该做的事情。

除了用户按下按钮然后在继续保持手指向下的情况下,将手指移动到按钮区域之外时,这一切都很棒。当手指抬起时,无论如何都会运行ACTION_UP。我希望这种行为充当"取消"按下按钮。因此,只要按下的手指移动到按钮区域之外,我就想b.setPressed(false);,然后在手指抬起时不做按钮动作。

我已尝试使用MotionEvent.ACTION_CANCELMotionEvent.ACTION_OUTSIDE(由How to detect when finger slides off the ImageButton?建议),但我必须遗漏一些因为他们无法正常工作。

Detect when a user moves off of a button in Android开始,可以使用event.getX()event.getY()完成此操作。如果getX()是否定的,那么你就离开了左边,如果getY()是否定的,那么你就会离开顶部,但要弄清楚你是不是从右边或底部开始了我的意思必须弄清楚按钮的大小然后......必须有一个更简单的方法。有吗?

2 个答案:

答案 0 :(得分:3)

你得到了正确的答案。使用getWidth()getHeight()获取宽度和高度,并检查x或y是否更大。

ACTION_CANCEL无法正常工作,因为当父视图控制了触摸事件时会生成CANCEL,就像滚动时ListView一样。

ACTION_OUTSIDE仅在您请求的某些特殊情况下发生。它不会仅针对正常MOVEUP生成。

答案 1 :(得分:0)

由于没有人发布任何代码,这里只有一个。布尔值用于指示何时应执行相应的操作。

处理MotionEvent.ACTION_MOVE事件以检查手指是否移出界限。如果是,则调用b.setPressed(false);并使用布尔值表示下次不应触发MotionEvent.ACTION_UP,即取消按钮点击。

MotionEvent.ACTION_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;
});