这是我非常标准的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_CANCEL
和MotionEvent.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()是否定的,那么你就会离开顶部,但要弄清楚你是不是从右边或底部开始了我的意思必须弄清楚按钮的大小然后......必须有一个更简单的方法。有吗?
答案 0 :(得分:3)
你得到了正确的答案。使用getWidth()
和getHeight()
获取宽度和高度,并检查x或y是否更大。
ACTION_CANCEL
无法正常工作,因为当父视图控制了触摸事件时会生成CANCEL
,就像滚动时ListView
一样。
ACTION_OUTSIDE
仅在您请求的某些特殊情况下发生。它不会仅针对正常MOVE
或UP
生成。
答案 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;
});