Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android View stops receiving touch events when parent scrolls

Tags:

android

scroll

I have a custom Android view which overrides onTouchEvent(MotionEvent) to handle horizontal scrolling of content within the view. However, when the ScrollView in which this is contained scrolls vertically, the custom view stops receiving touch events. Ideally what I want is for the custom view to continue receiving events so it can handle its own horizontal scrolling, while the containing view hierarchy deals with vertical scrolling.

Is there any way to continue receiving those motion events on scroll? If not, is there any other way to get the touch events I need?

like image 424
Adrian Avatar asked Sep 08 '10 14:09

Adrian


People also ask

How are Android touch events delivered?

The touch event is passed in as a MotionEvent , which contains the x,y coordinates, time, type of event, and other information. The touch event is sent to the Window's superDispatchTouchEvent() . Window is an abstract class. The actual implementation is PhoneWindow .

Which method you should override to control your touch action android?

you override the onTouchEvent() method. The MotionEvent class contains the touch related information, e.g., the number of pointers, the X/Y coordinates and size and pressure of each pointer. This method returns true if the touch event has been handled by the view.

Which method you should override to control your touch action?

To make sure that each view correctly receives the touch events intended for it, override the onInterceptTouchEvent() method.


1 Answers

Use requestDisallowInterceptTouchEvent(true) in the childview to prevent from vertical scrolling if you want to continue doing horizontal scrolling and latter reset it when done.

private float downXpos = 0;
private float downYpos = 0;
private boolean touchcaptured = false;
@Override
public boolean onTouchEvent(MotionEvent event) {
    switch(event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        downXpos = event.getX();
        downYpos = event.getY();
        touchcaptured = false;
        break;
    case MotionEvent.ACTION_UP:
        requestDisallowInterceptTouchEvent(false);
        break;
    case MotionEvent.ACTION_MOVE:
        float xdisplacement = Math.abs(event.getX() - downXpos);
        float ydisplacement = Math.abs(event.getY() - downYpos);
        if( !touchcaptured && xdisplacement > ydisplacement && xdisplacement > 10) {
            requestDisallowInterceptTouchEvent(true);
            touchcaptured = true;
        }
        break;
    }
    super.onTouchEvent(event);
    return true;
}
like image 155
Prakash Nadar Avatar answered Nov 15 '22 09:11

Prakash Nadar