Android :: OnTouchListener && OnClickListener combination issue

17,790

Solution 1

you may call View.performClick() when action_up. Hope it helps.

your_txtView.setOnClickListener(new TextView.OnClickListener(){
        public void onClick(View v) {
            // TODO Auto-generated method stub

        }
    });

    your_txtView.setOnTouchListener(new TextView.OnTouchListener(){
            @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (MotionEvent.ACTION_DOWN == event.getAction()) {

        } else if (MotionEvent.ACTION_UP == event.getAction()) {
            v.performClick();
        }

        return true;
    }
    });

Solution 2

Adel, is the problem with the first click, or you don't get any click at all?

There is this issue if you have multiple clickable layout you don't get any click events for the first. That's because it makes it first selected and then you get the click event, try the below code.

private class CustomTouchListener implements OnTouchListener {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        TextView tv = (TextView) v.findViewById(R.id.single_line_text);
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            tv.setTextColor(COLOR_WHEN_PRESSED);
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            tv.setTextColor(COLOR_WHEN_RELEASED);
            // Action of click goes here
        } else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
            tv.setTextColor(COLOR_WHEN_RELEASED);
                            // To handle release outside the layout region
        }
        return false;
    }
}

This is working in my current implementation if you set the touch listener for your layout.

You also need to set below on your layout

android:focusable="true"
android:focusableInTouchMode="true"
android:clickable="true"

Hope it helps!!!

EDIT: Additionally, there should be a flag in both DOWN and UP. Set it in DOWN and check if its set in UP. This will avoid a bug where user might tap anywhere in the screen and then hover on your textview and release it.

Solution 3

Had the same problem. Solved it by returning false from ACTION_MOVE. I've been fighting with it for few hours, trying various things, but seems like i've kept overlooking this little issue... And now it makes sense. When you return true from onTouch, futher processing is stopped, so that OnClickListener is not aware of any movements and triggers onClick even after pointer have moved outside of view.

Share:
17,790
Admin
Author by

Admin

Updated on August 21, 2022

Comments

  • Admin
    Admin almost 2 years

    Problem description:

    I have a TextView on a RelativeLayout and I want to color it red when the user touches it, and go on another page when he clicks on it. So I tried to set an OnClickListener to do the click, and an OnTouchListener to implement the touch function (MotionEvent.ACTION_DOWN) but this combination doesn't work, because OnTouchListener makes OnClickListener non-functional (don't know why).

    On forums people say that we can implement the OnClick by the OnTouch MotionEvent.ACTION_UP, but this one can be triggered out of my TextView layout (the TextView gonna be clicked if you press it and drag your finger out of him to release) and this is not the desired behavior because I want:
    click = press + release on the TextView.

    Can someone give me a solution for this please?

  • Dany's
    Dany's about 12 years
    i had the same problem...and v.performClick work beautiful...this is the solution...please accept the answer
  • harsimranb
    harsimranb almost 12 years
    Many thanks! You definitely helped me out. The trick for me was to set the three properties you stated...
  • Gatekeeper
    Gatekeeper almost 12 years
    Thanks for the help! I was missing the android:focusable="true" in my TextView
  • aNoviceGuy
    aNoviceGuy over 10 years
    Thank You sven. This is awesome.
  • gturri
    gturri over 10 years
    On behalf of @bugs99 who can't add comment because of a lack of reputation: By changing the return true to return false, you can perform the onTouchListener() action and then pass the touch event to the onClickListener(). With this, there is no need to explicitly perform the performClick()
  • Georg
    Georg over 9 years
    Hm.... what if the 'TouchListener' is on a view above the button that should get the click if my TouchListener decides that the event is not a swipe? Any ideas on how to pass that to any view underneath?