7

In my layout I have a structure like that:

--RelativeLayout
  |
  --FrameLayout
    |
    --Button, EditText...

I want to handle touch events in the RelativeLayout and in the FrameLayout, so I set the onTouchListener in these two view groups. But only the touch in the RelativeLayout is captured.

To try solve this, I wrote my own CustomRelativeLayout, and override the onInterceptTouchEvent, now the click in the child ViewGroup (FrameLayout) is captured, but the click in the buttons and other views doesn't make any effect.

In my own custom layout, I have this:

public boolean onInterceptTouchEvent(MotionEvent ev) {
    return true;
}
androidevil
  • 9,011
  • 14
  • 41
  • 79

3 Answers3

7

You need to override the onInterceptTouchEvent() for each child, otherwise it will remain an onTouchEvent for the parent.

Intercept Touch Events in a ViewGroup

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    /*
    * This method JUST determines whether we want to intercept the motion.
    * If we return true, onTouchEvent will be called and we do the actual
    * scrolling there.
    */
...
    // In general, we don't want to intercept touch events. They should be 
    // handled by the child view.
    return false;
}

You need to return false to have the child handle it, otherwise you are returning it to the parent.

Csaba Toth
  • 10,021
  • 5
  • 75
  • 121
  • 2
    Suppose I want to override the touch events only for handling some of the children, what can I do inside this function to have it working ? I mean, for some children it would work as usual, and for some, the parent-view will decide if they will get the touch events or not. – android developer Jun 21 '15 at 14:58
1

Your custom solution will capture touch events from anywhere in your relative layout since the overridden method is set to always throw true.

For your requirement I guess its better to use the onClick method rather than using onTouch.

OnTouch method invokes different threads on every TouchEvent and I guess that is the cause of your problem

Rather than handling these events its better to try onClick method.

testuserx
  • 226
  • 2
  • 13
1

I was able to solve this problem with the following code:

Step 1: declare the EditText above the onCreate () method

public EditText etMyEdit;

Step 2: in the onResume () method the configuration ends:

etMyEdit = (EditText) findViewById (R.id.editText);

etMyEdit.setOnTouchListener(new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {
            v.getParent().requestDisallowInterceptTouchEvent(true);
            switch (event.getAction() & MotionEvent.ACTION_MASK){
                case MotionEvent.ACTION_UP:
                    v.getParent().requestDisallowInterceptTouchEvent(false);
                    return false;
            }
            return false;
        }
    });

Hope it helps someone!