Introduction:

When the Android system captures various input events from the user, how does it accurately pass the event to the controls that really need it? Android provides us with a complete set of event delivery and processing mechanisms to help developers complete the accurate event allocation and processing.

The main content

  • Understand the MotionEvent
  • Understand event interception mechanisms

The specific content

To understand the interception mechanism for touch events, we first need to know what are touch events? As the name suggests, touch events capture events occurring behind the scenes of the touch screen. When a button is clicked, there are usually two or three events — button down, that’s event one; If I slip a little bit, this is event two; When the hand is raised, this is event three. Android encapsulates a class called MotionEvent for touch events, and if you override the onTouchEvent() method, you’ll find that the argument given to the method is such a MotionEvent. In fact, whenever you override touch related methods, the parameter usually contains MotionEvent, which shows its importance. In this way, the touch event is relatively simple, just an action type plus coordinates. But as we know, Android View structure is a tree structure, that is, the View can be placed in the ViewGroup, through different combinations to achieve different styles. So the problem is, a View is in a ViewGroup, and that ViewGroup is in another ViewGroup, and maybe even nested, and layered on top of each other. But we only have one touch event. Who should we share it with? Both the child View and the parent ViewGroup might want to handle the same event. Hence the “domineering” term “event interception”.

MotionEvent

MotionEvent encapsulates a number of nice things, such as the coordinates of touch points, which can be retrieved using the event.getx () and event.getrawx () methods. Another example is the type of event that gets a click, which can be distinguished by different actions and implemented with different logic.

There are three types of Action:

  • Motionevent.action_down, triggered when pressed.
  • MotionEvent.ACTION_MOVE, triggered when moving.
  • Motionevent.action_up, triggered when lifting.

The code looks like this:

@Override
public boolean onTouchEvent(MotionEvent event) {
    switch(event.getAction()) {
        // Triggered when pressed.
        case MotionEvent.ACTION_DOWN:

        break;
        // Triggered when moving.
        case MotionEvent.ACTION_MOVE:

        break;
        // Trigger when lifting.
        case MotionEvent.ACTION_UP:

        break; }}Copy the code

Event interception mechanism

Event interception can be complex or simple. But beginners often get stuck here and don’t know how to proceed, so we don’t want to overwhelm you with too much source code. We through the most intuitive Log information, let you have a general understanding, know the nature of event interception, and then you can have direction, purposeful to understand when combined with source code learning. First of all, please imagine a very common situation in your life: suppose you work for a company, there is a general manager, the most senior; He has a minister below him, the next most senior; The lowest level, the working you, has no rank. Now the board gives the general manager a task, and the general manager gives it to the minister, who gives it to you. And when you are not easy to finish the job, you give the task to the minister, the minister feel that the task is done well, so he signed his name to the general manager, the general manager read also feel good, employment signed the name to the board of directors. In this way, a task is successfully completed. If you can understand this scenario very clearly, then you are over 40% of the developers for event blocking. Now, let’s leapfrog the rest of the developers. In order to easily understand the process of the whole event, we designed such an example.

  • A general manager — MyViewGroupA, outermost ViewGroup (red).
  • One length — MyViewGroupB, ViewGroup in the middle (green).
  • A working you, MyView, is at the bottom (blue).

The entire layout structure of this example is shown below.

The code is very simple, just rewriting a few methods for event interception and handling, and adding some logs to it. For viewGroups, the three methods shown below are overridden.

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    Log.d("cc"."ViewGroupA dispatchTouchEvent" + ev.getAction());
    return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    Log.d("cc"."ViewGroupA onInterceptTouchEvent" + ev.getAction());
    return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
    Log.d("cc"."ViewGroupA onTouchEvent" + event.getAction());
    return super.onTouchEvent(event);
}
Copy the code

For View, we override the two methods shown below.

@Override
public boolean onTouchEvent(MotionEvent event) {
    Log.d("cc"."View onTouchEvent" + event.getAction());
    return super.onTouchEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    Log.d("cc"."View dispatchTouchEvent" + event.getAction());
    return super.dispatchTouchEvent(event);
}
Copy the code

As you can see from the code above, the ViewGroup level is higher, with one more method than View: onInterceptTouchEvent(). This method is, as the name suggests, the core method of event interception. Let’s not change any of the return values, just click on the View, and see how the Log records our actions and program responses. The Log after clicking View is shown below.

D/cc: ViewGroupA dispatchTouchEvent0 
D/cc: ViewGroupA onInterceptTouchEvent0 
D/cc: ViewGroupB dispatchTouchEvent0 
D/cc: ViewGroupB onInterceptTouchEvent0 
D/cc: View dispatchTouchEvent0 
D/cc: View onTouchEvent0 
D/cc: ViewGroupB onTouchEvent0 
D/cc: ViewGroupA onTouchEvent0
Copy the code

As you can see, the normal order of events is:

  • General Manager (MyViewGroupA)→ Minister (MyViewGroupB)→ you (View). For event passing, the dispatchTouchEvent() method is followed by the onInterceptTouchEvent() method.

The sequence of events is as follows:

  • You (View)→ Minister (MyViewGroupB)→ General Manager (MyViewGroupA). Event handling is done by executing the onTouchEvent() method.
  • The return values of the event pass are easy to understand: true, intercept, do not continue; False, do not intercept, continue the process.
  • The event handler returns a similar value: true, processed, not audited; False, send it to the superior.
  • Initially, the return value is always false.

We only care about onInterceptTouchEvent(). DispatchTouchEvent () is the first step in event distribution, but we generally don’t want to rewrite it. So let’s not do that for now. The whole process can be organized into the following diagram.

I believe that as long as you think of MyView as yourself, you can fully understand the whole process of event distribution, interception, processing. Let’s change it a little bit and assume that the general manager (MyViewGroupA) finds the task so easy that he thinks he can do it himself and doesn’t need a subordinate at all. So the event is intercepted by the general manager (MyViewGroupA) using the onInterceptTouchEvent() method, which returns true.

D/cc: ViewGroupA dispatchTouchEvent0 
D/cc: ViewGroupA onInterceptTouchEvent0 
D/cc: ViewGroupA onTouchEvent0
Copy the code

As we expected, the general manager (MyViewGroupA) took care of everything, leaving no one behind. If MyViewGroupB returns true from the onInterceptTouchEvent() method, the Log will do the following.

D/cc: ViewGroupA dispatchTouchEvent0 
D/cc: ViewGroupA onInterceptTouchEvent0 
D/cc: ViewGroupB dispatchTouchEvent0 
D/cc: ViewGroupB onInterceptTouchEvent0 
D/cc: ViewGroupB onTouchEvent0 
D/cc: ViewGroupA onTouchEvent0
Copy the code

As you can see, this time the minister (MyViewGroupB) is the good guy, so you (MyView) don’t have to do any work. Then these two cases can also be arranged into something like the figure above.

  • The general manager (MyViewGroupA) intercepts events, as shown in the figure below.

  • The minister (MyViewGroupB) intercepts the event, as shown below.

Distribution of events, interception, now we should be more clear, let’s look at the event processing. Let’s start with the bottom people — you (MyView). As we said at the beginning, when you’re done with a task, you report it to your supervisor and need confirmation, so your event handler returns false. If you are on strike one day, you can’t stand the pressure of your boss. If you are on strike one day, you can’t work, so you don’t have to report on the computer. Now look at the Log, as shown below.

D/cc: ViewGroupA dispatchTouchEvent0 
D/cc: ViewGroupA onInterceptTouchEvent0 
D/cc: ViewGroupB dispatchTouchEvent0 
D/cc: ViewGroupB onInterceptTouchEvent0 
D/cc: View dispatchTouchEvent0 
D/cc: View onTouchEvent0
Copy the code

As you can see, event passing is the same as it was before, but event processing ends up at you (MyView), because you return true, which means you don’t have to report it to your superiors. At this point, let’s also arrange the diagram, as shown below.

You (MyView) finally turned over to be the master, decided their own fate. However, if the minister (MyViewGroupB) sees your report and is too embarrassed to show it to the manager, so he secretly returns True and that’s the end of the story, that is, the minister (MyViewGroupB) returns its own onTouchEvent, Log as shown below.

D/cc: ViewGroupA dispatchTouchEvent0 
D/cc: ViewGroupA onInterceptTouchEvent0 
D/cc: ViewGroupB dispatchTouchEvent0 
D/cc: ViewGroupB onInterceptTouchEvent0 
D/cc: View dispatchTouchEvent0 
D/cc: View onTouchEvent0 
D/cc: ViewGroupB onTouchEvent0
Copy the code

The diagram of their relationship is shown below.

Through the analysis of the previous several cases, I believe that we can easily understand the event distribution, interception, event processing process. Later in the study, combined with the source code, you will have a deeper understanding of why the process is the way it is. In learning, it is best to have a general understanding of the process, and then to contact the source code, so that it will not be confused, confused, thus losing interest in learning.