5

Given that there is a ViewGroup with several children. As for this ViewGroup, I'd like to have it managing all MotionEvent for its all children, which says VG will
1. be able to intercept all events before they get dispatched to target (children)
2. VG will first consume the event, and determine if will further dispatch event to target child
3. DOWN, MOVE, UP, I'd like to see them as relatively independent, which means VG could eat DOWN, but give MOVE and UP to children.

I've read SDK guide "Handling UI Event", I knew event listeners, handlers, ViewGroup.onInterceptTouchEvent(MotionEvent), and View.onTouchEvent(MotionEvent).

Here's my sample,

@Override
public boolean onInterceptTouchEvent (MotionEvent event) {
    if (MotionEvent.ACTION_DOWN == event.getAction()) {
        return true;
    }

    return super.onInterceptTouchEvent(event);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (MotionEvent.ACTION_DOWN == event.getAction()) {            
        return true;
    }
    else {
        if (!consumeEvent(event)) {
            // TODO: dispatch to target since I didn't want to eat event
            //return this.dispatchTouchEvent(event);     // infinite loop!!!
        }
    }


    return super.onTouchEvent(event);
}

To be able to eat some events, I have to return true in above both methods when DOWN event occurred, because SDK said so. Then I could see MOVE and up in onTouchEvent. However, in my case, I've no idea about how to dispatch event to children.

Above dispatchTouchEvent led to infinite loop, which was understandable, since VG itself might be the target. I can't tell which would be target at that moment, MotionEvent didn't give a hint, so dispatchTouchEvent was totally useless.
Anyone help me out? Thanks.

fifth
  • 4,249
  • 9
  • 45
  • 62
  • can you do any help to me in this situation [My Problem](http://stackoverflow.com/questions/13309111/programatically-execute-another-touch-event-when-one-touch-event-occures-in-andr), or in [Other Question](http://stackoverflow.com/questions/12980156/detect-touch-event-on-a-view-when-dragged-over-from-other-view) – Chintan Raghwani Nov 16 '12 at 09:15

1 Answers1

4

There is no easy way to find the source View from onInterceptTouchEvent, nor there is a way to "dispatch" these events. You can dispatch KeyEvents, but not MotionEvents.

A common way to deal with MotionEvents (e.g., for drag and drop) is to handle the MotionEvent.ACTION_DOWN events by the different Views (through the onTouch callback after implementing OnTouchListener), and the MotionEvent.ACTION_MOVE events through the parent Viewgroup's onInterceptTouchEvent method.


But some LOCs say a lot more than a bunch of words. There's a very nice example of what I'm saying here: http://doandroids.com/blogs/tag/codeexample/


If you handle the ACTION_DOWN event in the View itself, then you can store which View started it elsewhere and use that variable for further actions. The Event is bound to the same View until is finished by an ACTION_UP or an ACTION_CANCEL actions.

If you need to keep track the View and execute an action on the ViewGroup during the ACTION_DOWN, then I suggest you to add a public method in your ViewGroup (e.g. public boolean handleActionDown (View v, MotionEvent e) that will be called from the onTouch callback

Aleadam
  • 40,203
  • 9
  • 86
  • 108
  • Thanks. If let children handle DOWN and parent VG got MOVE or UP, it still couldn't dispatch MOVE/UP to real target if necessary. For children, the very first DOWN event should be intercepted on demand. And the interception rule is applied to every DOWN/MOVE/UP. I think my case is not quite similar as your Drag & Drop. – fifth May 09 '11 at 03:33
  • @fifth I replied in my answer because it was too long for a comment. – Aleadam May 09 '11 at 03:45
  • ok, got your idea. Storing target view first is the key, later I'm able to dispatch it. – fifth May 09 '11 at 06:11
  • @fifth yep. It's either that or starting to guess your View based on the x and y coordinates, which can be messy. – Aleadam May 09 '11 at 06:17
  • @Aleadam, I'm thinking of installing a supervising OnTouch listener for every view. The tedious job would be that I have to iterate every child if there is a component view added, and I have to recursively do so. – fifth May 09 '11 at 07:10
  • I've done with above solution. By setting up a OnHierarchyChangeListener.onChildViewAdded, in which I could register OnTouchListener to every child view, then I can handle events as expected. – fifth May 09 '11 at 08:51
  • @fifth, can you do any help to me in this situation [My Problem](http://stackoverflow.com/questions/13309111/programatically-execute-another-touch-event-when-one-touch-event-occures-in-andr), or in [Other Question](http://stackoverflow.com/questions/12980156/detect-touch-event-on-a-view-when-dragged-over-from-other-view) – Chintan Raghwani Nov 16 '12 at 09:14