2

I observe this weird behavior, please help me figure it out!

I simply set a onTouchListner to a button. For the onTouch() callback, if I set it return false, when I click on the button, I can see the click animation effect of the button (simply color change); However, if I set it return true, when I click on the button, the click animation effect just disappeared.

Below is the code

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btn = findViewById(R.id.btn);
        btn.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                v.setClickable(true);
                Log.d("myTrack", "onTouch");
                return true;  // I cannot see the animation effect when click
                return false; // I can see the animation effect when click
            }
        });
    }
}

1 Answers1

1

I observe this weird behavior, please help me figure it out!

This is default behaviour of Android.

If you return true from an ACTION_DOWN event you are interested in the rest of the events in that gesture. A "gesture" in this case means all events until the final ACTION_UP or ACTION_CANCEL. Returning false from an ACTION_DOWN means you do not want the event and other views will have the opportunity to handle it. If you have overlapping views this can be a sibling view. If not it will bubble up to the parent.

So when you return true, you have told android that you have handled all events, and it has nothing to do with. So you don't see any ripple effects even.

Khemraj Sharma
  • 57,232
  • 27
  • 203
  • 212
  • Is there any to edit this default behavior? like manually add ripple effect while still returning true? – user7055721 Apr 23 '18 at 05:50
  • Tell me your requirement, so i can tell you best solution. – Khemraj Sharma Apr 23 '18 at 05:57
  • Ok, the whole story is: I have a onClickListener() and onTouchListener() on the same view. I want `onClick` to handle single click, and `onTouch` with `GestureDetector` to handle doubleTap. I don't want to fire `onClick` when I double tap, that's why I want my `onTouch()` callback to return true, indicating that this event has been consumed, so it won't be passed to onClick. But I also don't want to lose the ripple effect by returning true – user7055721 Apr 23 '18 at 06:50
  • Is moving all code from `onClick` to `onSingleTapConfirmed` under `onTouchListener` and abandon `onClickListener` the only way to handle this? – user7055721 Apr 23 '18 at 06:50
  • Do these questions help you? https://stackoverflow.com/q/14724234/6891563 and https://stackoverflow.com/a/13324574/6891563 – Khemraj Sharma Apr 23 '18 at 08:24