Android: ViewGroup, how to intercept MotionEvent and then dispatch to target or eat it on demand?
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 eve开发者_如何学Gont 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.There is no easy way to find the source View
from onInterceptTouchEvent
, nor there is a way to "dispatch" these events. You can dispatch KeyEvent
s, but not MotionEvent
s.
A common way to deal with MotionEvent
s (e.g., for drag and drop) is to handle the MotionEvent.ACTION_DOWN
events by the different View
s (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
精彩评论