代码之家  ›  专栏  ›  技术社区  ›  Mark Cramer

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

  •  2
  • Mark Cramer  · 技术社区  · 10 年前

    这是我在TouchListener上的标准按钮:

    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()为负数,那么你就在上面,但是要想知道你是在右边还是在下面,我必须计算出按钮的大小,然后。。。必须有一种更简单的方法。有?

    2 回复  |  直到 7 年前
        1
  •  3
  •   Divins Mathew Pentium10    7 年前

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

    ACTION_CANCEL 不起作用,因为 CANCEL 当父视图控制触摸事件时生成,如 ListView 当滚动时。

    ACTION_OUTSIDE 只有在一些不寻常的情况下,你才会请求它。它不会只为一个正常的 MOVE UP .

        2
  •  0
  •   Divins Mathew Pentium10    7 年前

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

    这个 MotionEvent.ACTION_MOVE 事件被处理以检查手指是否移出边界。如果是, b.setPressed(false); 并且布尔值用于指示 MotionEvent.ACTION_UP 下次不应该被解雇(取消按钮点击)。

    并且在 运动事件.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;
    });