Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass touch event to Parent View's onTouchListener in Android

Tags:

android

I have a list view whose item is a linearlayout which has a button as it's child view. I want the ontouchLIstener of the linearlayout to work. I don't want to use onInterceptTouchEvent. Is there a way a I can pass on the touch form the button to the parent listview. I tried this - returning true from the button's onTouchListener

private View.OnTouchListener buttonListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            Log.i(TAG, "Button On Touch");
            return true;
        }
};

But this does not work. It does not pass on the touch event to the linearlayout's onTouchListener.

There must be someway it should work.

like image 620
Ashwin Avatar asked Oct 22 '25 05:10

Ashwin


2 Answers

The chain of events for a View group works like this - The dispatchEvent is called. Then dispatchEvent calls onInterceptTouchEvent. if it returns false, then the touch events are passed on to the children of the ViewGroup. If any of the children consume the event (in this case the button consumes the event) i.e if they return true then the motionevent is not passed on to other methods. Since the button is clickable it returns true in this case.

If the onInterceptTouchEvent method returns true then the child views are not given the motion event and instead that ViewGroup's onTouchListener or onTouch method are called.
Hence to pass on the touch event to the parent's (View Group) onTouchListener make sure to return true in the onInterceptTouchEvent method of the Parent (ViewGroup). You don't have to override onDispatchTouchEvent()

@Override
    public boolean onInterceptTouchEvent(MotionEvent motionEvent) {

        Log.i(TAG,"PARENT.onInterceptTouchEvent");

        return true;
}

For more details about how the touch navigation is done, please see this stack post

like image 155
Ashwin Avatar answered Oct 24 '25 20:10

Ashwin


Set your button clickable property to false, using:

button.setClickable(false);

Then in onTouch of button:

return false;

Note: This behavior is specific to button (and any other view that has clickable property set to true) that even if you return false from onTouch it will not propagate event to the parent and onClick method of the button will be called anyway.


EDIT: Another way is extending ListView class and overriding onInterceptTouch:

public class CustomListView extends ListView {
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // here you can listen for button touch events
    }
}
like image 26
semsamot Avatar answered Oct 24 '25 20:10

semsamot



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!