Mastering the Android Touch system
1. How Android Deal With Touch?
So every event that comes from the touch screen on the device into your application is wrapped up in one of these MotinEvents
. The MotionEvent
essentially provides you all the information that you need associate with each event as to what the event action was, as well as any additional meta data that may be necessary such as the touch’s location, the number of fingers that we on the screen at that time, the actual event time itself, anything you might need to process that information and use that inside your application.
There is number of primary useful actions, and by their name you can probably figure out what they are, but just to kind give you a basic idea, the actions below describes user’s current action:
- ACTION_DOWN
- ACTION_UP
- ACTION_MOVE
- ACTION_POINTER_DOWN
- ACTION_POINTER_UP
- ACTION_CANCEL
ACTION_DOWN and ACTION_UP those are the primary actions when the first pointer or finger comes in contact with the screen and then that released; ACTION_MOVE is an event that is happening as that pointer is dragging around the screen; ACTION_POINTER_DOWN and ACTION_POINTER_UP will be seen for secondary or additional fingers or pointers as they coming contact with the screen, so these are whtat you’ll see and what you need to look for when you dealing with multi-touch; And then finally ACTION_CANCEL has to do primarily with when events are initially handled by one view and then that is transferred over to another .
The primary thing to keep in mind and you’ll see the theme sort of coming in and out is that Android really defines a single gesture as all the events that happen between an ACTION_DOWN event and an ACTION_UP event. So the ACTION_DOWN is sort of the initialization of an new gesture that you would be handling in your application and basically the state that is maintained though that gesture through all the different move events and things like that is then terminated on ACTION_UP. That’s sort of resets the whole game and starts over. You’ll see that theme kind of come through couple different times.
How Android Handles Touches?
How does these things actually flow through your application? so for every event that as generated by the hardware and the underlying framework, they are first dispatched to your application is Activity
, whatever the foreground Activity is at the top level inside your application that Activity will receive the touch event before any other component inside of your app. It will do that by the framework calling the disptchTouchEvent()
method on that Activity.
I first point this out to say is for whatever reason in your app you need to gain knowledge of or get understanding of touch event before anything else in your app does, the very first opportunity you have at all to see a touch event is the dispatchTouchEvent()
on Activity, so you can override that method and inspect those motion events there. I wouldn’t necessarily recommend doing a whole lot with them other than just monitoring them, cause they have a long way to go still through the framework. But this is the first method that we’ll ever be called.
And then, in that point, these events are going to traversal their way down from the Activity down through from your view hierarchy from the top down, so they are gonna start at the Activity in the window level and they will be first delivered to the RootView
of whatever your content ViewGroup
is and then that ViewGroup
’s job is to deliver it to its childViews, and if those are ViewGroups, to their childView all the way down the tree to way get the bottom, and then if necessary traversal those back up.
The way that this works is the events will flow through your app until such point that one of the views declares that is interested in that event and wants to know more about the rest of the gesture, the way the framework does this is the onTouchEvent()
method in each View or ViewGroup has, returns a boolean value. And so as a implementer of a custom view or some other piece of the view hierarchy, your app can return true from this method to declare interest in that particular gesture. And at that point, the framework has found a view that is interested in the touch and it will stop that respond chain, but essentially if a touch event manges to go all the way down the view hierarchy and not find a single view that is interested in that touch, it will start to work back up to the hierarchy until it gets all the way back to the activity.
The core thing to com a way with that is if you are trying to do any custom touch handling, the ACTION_DOWN
event is something that your View or ViewGroup need to return true for if you’re interested in that event or any events after that effect, cause if you don’t declare interest in ACTION_DOWN, there is a good chance you may not see another touch event at all at that point. For efficiency reasons once a particular View has declared an interest and has returned true, that is the effective destination for all the other MotionEvent for the reminder of that gesture.
The way that this hierarchy basically works is that they will traversal down through the Views and ViewGroups by individually calling the dispatch methods of each, so the ViewGroup will dispatch to the View and so on and so forth. And then as they work back up it’s the onTouchEvent() that get called, effectively, the diaptch methods go on the way down, and onTouch on the way back up.
The Activity’s onTouchEvent() is the last place the touch event will end up, and in many cases that they may not show up at all, cause if a touch event is consumed by some View lower down in the tree, that’s where it stops. So anything after that on the way back up won’t be called at all.
[To be continue…]