Android: 检测 ACTION_UP 按钮外的事件

Android: Detect ACTION_UP event outside button

我在使用自己构建的自定义按钮时遇到了一些问题。它由一个方框和下方的一条小线组成。

按钮在您按下时垂直向下动画,在您松开时再次向上动画。这是在 CustomButton.class:

中处理的
super.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
                    buttonContent.startAnimation(rectMoveDown);
                    colorDown.start();
                    return false;
                }
                if (event.getActionMasked() == MotionEvent.ACTION_UP) {
                    buttonContent.startAnimation(rectMoveUp);
                    colorUp.start();
                    return false;
                }
                return false;
            }
        });

然后在应用程序的其余部分,我使用此按钮并为其设置一个点击监听器。因此我 return false(我认为这至少是正确的)因为我不想使用该事件,而是将其传递给层次结构中的 clicklistener。

但是,当我先按下按钮,将手指移到按钮外,然后松开屏幕时,问题就出现了。然后按钮不显示在 ACTION_UP 侦听器中完成的动画。

有人知道如何解决这个问题吗?

经过更多测试,我找到了解决方法!

在阅读了更多文档后,我发现 MotionEvent.ACTION_CANCEL 完全符合我的需要:

The current gesture has been aborted. You will not receive any more points in it. You should treat this as an up event, but not perform any action that you normally would.

所以现在我的 TouchListener 看起来像这样(并且工作正常):

super.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getActionMasked()) {
                    case MotionEvent.ACTION_DOWN:
                        buttonContent.startAnimation(rectMoveDown);
                        colorDown.start();
                        return false;
                    case MotionEvent.ACTION_UP:
                    case MotionEvent.ACTION_CANCEL:
                        buttonContent.startAnimation(rectMoveUp);
                        colorUp.start();
                        return false;
                }
                return false;
            }
        });

不是我开始用switch-case解决了,而是为了让代码好看改成switch-case。如您所见,我以完全相同的方式处理 ACTION_UP 和 ACTION_CANCEL。

我 return 到处都是假的,以便触发 OnClickListener,如果我 return 为真,它就不会触发。