Android Event Distribution mechanism understanding

Source: Internet
Author: User

Pre-Knowledge Touch Events:
    1. Wirelessly encapsulates a touch event into a class motionevent, where a user's one click, Touch, or swipe produces a series of motionevent
    2. The content of this class is simple, just two things: event type + coordinate XY
    3. There are four types of events
      1. Motionevent.action_down indicates that the user's finger has just touched the screen
      2. Motionevent.action_move indicates that the user's finger is moving
      3. MOTIONEVENT.ACTION_UP indicates that the user's finger is lifted from the screen
      4. Cancel
    4. So once the user touches the screen it may produce these events:
      1. Tap the screen and release, Down->up
      2. Tap the screen, then swipe a distance, release the screen, Down->move->...->move->up
Event Distribution method:In the process of event distribution, there are three main methods involved
    1. Dispatchtouchevent (Motionevent event)
    2. Onintercepttouchevent (Motionevent event)
    3. Ontouchevent (Motionevent event)
Assumptions:
    1. Consider only the four most important touch events, namely:down,move,up and Cancel
    2. A gesture (gesture) is an event column
      1. Start with a down event (generated when the user touches the screen)
      2. followed by 0 or more move events (resulting when the user moves the finger around)
      3. Last followed by a separate up or cancel event (when the user finger leaves the screen or the system tells you that the gesture (gesture) was generated due to other reasons)
    3. When we speak of "gesture remainder" , we refer to the gesture's subsequent move event and the last up or cancel event.
    4. Do not consider multi-touch gestures (we only assume one finger).
    5. Ignoring multiple move events can be categorized as a set of realities
    6. Suppose the view in this article is not registered Ontouchlistener
    7. Suppose a view hierarchy:
      1. The outermost layer is a viewgroup A, which contains one or more sub-view (children), where a child view is ViewGroup B,VIEWGROUPB and contains one or more child view, one of which is view C, C is not a viewgroup
      2. Ignore possible cross overlays between the same level view
    8. Hypothetical situation:
      1. The point on the screen that the user first touches is a point on C that is marked as a touch point, and the down event is generated at that point
      2. Then the user moves the finger and leaves the screen at last, and it doesn't matter if the finger leaves the area of C during this process, the key is where the gesture (gesture) starts.
    9. Assuming that the Dispatchtouchevent method is not considered
assuming no consideration Onintercepttouchevent, while When you do not overwrite the event distribution method:
    1. The down event is passed to the Ontouchevent method of C, and the method returns false, indicating "I don't care about this gesture (gesture)"
    2. Therefore, the down event is passed to the Ontouchevent method of B, and the method returns False, indicating that B does not care about the gesture.
    3. Similarly, because B does not care about this gesture, the down event is passed to the Ontouchevent method of a, and the method also returns false
    4. Since no view cares about this gesture (gesture), they will no longer receive any events from the rest of the gesture
(A better case description is to hit log to see which methods are called) assuming no consideration Onintercepttouchevent, but overriding event distribution (plus handling events)Suppose that C is actually concerned with this gesture (gesture), probably because C is set to clickable (clickable) or you override C's Ontouchevent method
    1. The down event is passed to the C Ontouchevent method, which can do anything it wants to do, and finally returns true.
    2. Because C says it is processing this gesture (gesture), the down event will no longer be passed to the Ontouchevent method of B and a.
    3. Because C says it is processing this gesture (gesture), the "gesture remainder" event is also passed to the Ontouchevent method of C, when the method returns TRUE or false is irrelevant, but it is best to return true for consistency.
As can be seen from here, the Ontouchevent method of each view handles the down event, which represents the intention of the view to handle the entire gesture starting with this down (gesture), which returns true to be willing to handle the gesture, Returns false to indicate reluctance to handle the gesture plus onintercepttouchevent but not intercept .
    1. Onintercepttouchevent method It exists only in ViewGroup, and there is no such method in normal view
    2. Before any of the view's ontouchevent is called, its fathers will first get a chance to intercept the event.
    3. In other words, they can steal the event. In the "Handling Events" section just now, we missed the process
Now let's add it, and here's the case:
    1. The down event is passed to the onintercepttouchevent of a, and the method returns false, indicating that it does not want to intercept.
    2. Down is passed to the onintercepttouchevent of B, and it does not want to intercept, so the method also returns false.
    3. The down event is now passed to the Ontouchevent method of C, which returns true because it wants to handle the gesture (gesture) that is headed with the event.
    4. Now, the next event move for the gesture has arrived. This move event is again passed to the Onintercepttouchevent method of a, which again returns FALSE,B.
    5. The move event is then passed to the C ontouchevent, as in the previous section.
    6. The other events in the "gesture remainder" process are treated as above, assuming that the Onintercepttouchevent method of A and B continues to return false.
Here are two points to note:
    1. Although the Onintercepttouchevent method of ViewGroup A and B returns false for the down event, subsequent events are still passed to their Onintercepttouchevent method, This is not the same as Ontouchevent's behavior.
    2. If the down event is passed to the Ontouchevent method of C, it returns the False,down event that will continue to be passed up to the ontouchevent of B and a. Even if they say in the Onintercepttouchevent method that they do not want to intercept the down event, the two are independent
Thus, the treatment of the down event actually experienced a two process, the next refers to the A->b onintercepttouchevent, refers to the C->b->a ontouchevent, of course, the method of any step returns true, Can prevent it from continuing to spread. in the onintercepttouchevent Intercept EventsLet's take a step further by assuming that B does not intercept the down event, but it intercepts the next move event. The reason may be that B is a scrolling view. When a user clicks (tap) in only its area, the clicked element should be able to handle the click event. But when the user's finger moves a certain distance, it is no longer possible to see the gesture (gesture) as a click-it is clear that the user wants to scroll. That's why B takes over the gesture (gesture). Here is the order in which the events are processed:
    1. The down events are sequentially passed to the Onintercepttouchevent method of A and B, and they all return false, because they do not yet want to intercept.
    2. The down event is passed to the C Ontouchevent method, which returns true.
    3. The Onintercepttouchevent method of a will still return false on subsequent arrival of the move event.
    4. b The Onintercepttouchevent method receives the move event, at which point B notices that the user's finger has moved farther than a certain threshold (or slop). Therefore, the Onintercepttouchevent method of B decides to return true, thereby taking over the subsequent processing of the gesture (gesture).
    5. The move event will then be turned into a cancel event, and the cancel event will be passed to the C Ontouchevent method.
    6. Now, another move event, which is passed to the Onintercepttouchevent method of a, does not care about the event, so the Onintercepttouchevent method continues to return false.
    7. At this point, the move event will no longer be passed to the Onintercepttouchevent method of B, which, once returned to true, will no longer be called. In fact, the move and the "gesture remainder" are passed to the Ontouchevent method of B (and thus not to the child view at all) (unless a decides to intercept the rest of the gesture).
    8. C never receive any events from this gesture (gesture).
Here are a few little things that might surprise you:
    1. If a viewgroup intercepts the initial down event, the event is still passed to the Ontouchevent method of the ViewGroup.
    2. On the other hand, if ViewGroup intercepts a halfway event (for example, move), the event will be turned into a cancel event and passed to the child view that previously handled the gesture (gesture). The Ontouchevent method for ViewGroup is no longer passed (whether it is an intercepted move or a system-generated cancel). Only the events that come again will be passed to the ViewGroup ontouchevent method.
From now on, you can go further:
    1. For example, overwrite requestdisallowintercepttouchevent,c can use this method to prevent B stealing events
    2. If you want to be a little bit crazier, you can write the Dispatchtouchevent method directly in your own viewgroup and do whatever you want to do with the events that pass in.
But then you may break some conventions, so be careful assuming that the type of event is not consideredAlso consider the first dispatch method, and log in three methods, you can see the event delivery process is like this (Android is well written) ViewGroup can say three words: I received, I forwarded, I tried to deal with the view can only say two words: I received, I'm trying to deal with an event passing in.
    1. Viewgroupa first received the event, saying that I had received
    2. But he doesn't deal with it first, it forwards it to the child view, and then says, I forwarded the
    3. VIEWGROUPB then received the incident, too, and said, I received the
    4. But he did not deal with it first, it forwarded to the child view, and then said, I forwarded the
    5. VIEWC finally received the incident, that also said, I received
    6. (--------above is the event delivery process, the following is the event handling process--------)
    7. He tried directly to deal with it, and said, I tried to deal with it
    8. (results found that they could not be processed, no consumption events, so the event of the original path back)
    9. VIEWGROUPB receive the returned event, then deal with the chant, and said, I try to deal with
    10. VIEWGROUPB also received the return event, also said, I tried to deal with
Three sentences corresponding to the ViewGroup method is (feel a bit strange, because the Chinese name is just to remember, in fact, not the intention)
    1. I received: Dispatchtouchevent [Dispatch, send]
    2. I forwarded: onintercepttouchevent [intercept]
    3. I try to deal with it: ontouchevent
And then all three of these methods have a return value
    1. The first two sentences are the event delivery process.
      1. Returns true, indicating interception, to which the interruption, will not go down;
      2. Returns FALSE, indicates no interception, and continues down.
    2. The third sentence is the event-handling process (exactly the same, but with a different meaning)
      1. Returns true, indicating interception, to which the interruption, will not go down;
      2. Returns FALSE, indicates no interception, and continues down.
    3. By default, three methods return False
      1. And each place can actually be changed to true, so that the loop is directly interrupted
      2. However, if true is returned in the Onintercepttouchevent method, it is not the direct end loop, but instead jumps to the corresponding ontouchevent loop, which is the event processing loop, and all the outer ontouchevent are executed
      3. Returns true in the Ontouchevent method, which is really a direct interrupt
While overriding the method, although Dispatchtouchevent is the first step, we generally do not rewrite it, so we generally focus on the latter two methods on the complexity of the flow of eventsThe flow of events is related to several factors:
    1. What this view is; Two cases: view, viewgroup; affects the number of callback methods
    2. What this method is; three cases:; two kinds of situations: event passing, event handling;
    3. What this method returns; two cases: true, false; affects whether the loop is ended
    4. The type of the event; four cases:down,move,up and Cancel ;
So this piece of logic is a bit messy ... Pseudo-code interpretation methodMany people use this pseudo-code to clarify the relationship between the three distribution methods (I personally feel that the understanding of the threshold is suddenly elevated):
Public Boolean dispatchtouchevent(Motionevent event) {
Boolean consume = false;
if (Onintercepttouchevent (event)) {
consume = Ontouchevent (event);
} Else {
consume = Child.dispatchtouchevent (event);
}
return consume;}
This is a good explanation:
    1. In Dispatchtouchevent, first call ViewGroup own Onintercepttouchevent method, determine whether you want to intercept
      1. If you intercept yourself at this time, call your own Ontouchevent method.
        1. If the Ontouchevent method returns True, the event is consumed and event delivery ends
        2. If False is returned to prove that this motionevent is not consumed this time, then the incident will be returned up to the upper level to continue processing;
      2. If the current ViewGroup Onintercepttouchevent returns false, then the Dispatchtouchevent method of its child view is called, so the event is passed down.
    2. If its sub-view does not work, then will return to call ViewGroup's Ontouchevent method, of course, this is not reflected in the pseudo-code
This is the ViewGroup layer of event distribution, of course, it is not so simple, it is only through a simple way to understand, in fact, in the real event distribution, there are many problems to note:
    1. A completed sequence of events starts with a down, may contain several moves in the middle, and then ends with a
    2. Once a view intercepts an event, the entire sequence of events where the current event is located will be handled by this view
      1. The reaction in the real code is that once the view intercepts the down event, then the move and up events will not call Onintercepttouchevent, and it is handled directly by it
      2. This also means that it is inappropriate to handle events in Onintercepttouchevent, because it is possible to have an event, but skip the Onintercepttouchevent method directly
      3. This also means that once a viewgroup does not intercept Action_down, then the other action of this sequence of events will not be received, so when dealing with action_down, it is particularly prudent to
      4. (Oh, so this is very clear, dispatch is just the entrance, it does nothing, then intercept is a first-time interception of the flag, will only be called once, finally Ontouch is really deal with things, according to different events to do different processing)
    3. Ontouchevent is to judge Motionevent action, because one click operation will call two times Ontouchevent method, once is Action_down, once is action_up, if hand slip, There will be a number of action_move.
    4. ViewGroup default does not intercept any events, the source code in the ViewGroup Onintercepttouchevent method returns the default is False
    5. The entire event distribution appears to be passed from the outside, the parent view passes the event to the child view, in theory, the child view has no way to affect the parent view of the event processing, but there is a marker bit, Requestdisallowintercepttouchevent method, through this method, the child view can affect the parent view of the event processing, which can be used to resolve the parent view and child view of the sliding conflict
Reference: http://www.jianshu.com/p/2be492c1df96

Android event distribution mechanism understanding

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.