Analysis of event distribution principle of Android view

As an Android Developer, view is the most contacted every day. Although Android view is not the four major components, its status is not lower than that of the four major components. The event distribution mechanism of view's core knowledge points is a stumbling block for many novice students, and it is basically asked during the interview. Understanding view events allows you to write better custom views and resolve sliding conflicts.

When you touch the screen with your finger, this process can be divided into the following three processes in Android:

From action_ Down to action_ Up ends what we call an event sequence

Under normal circumstances, no matter how coquettish your fingers operate on the screen, they will eventually appear in motionevent, which is nothing more than the following two actions.

Return true: indicates that the current event is consumed. It may be the ontouchevent of the current view or the dispatchtouchevent of the child view. The event is terminated and will not be delivered.

Return false: call the ontouchevent of the parent ViewGroup or activity. (no more down).

Return super.dispathertouchevent: continue to pass down (child view), or call the ontouchevent method of the current view;

Summary: it is used to distribute events, that is, the gate of the event sequence. If the event is passed to the ontouchevent of the current view or the dispatchtouchevent of the child view, that is, the method is called. In addition, if action is not consumed_ For the down event, the down, move and up events have nothing to do with the view and are handled by the parent class (ontouchevent method of the parent class)

Return true: the ViewGroup intercepts this event and gives it to its own ontouchevent to handle.

Return false: continue to process the dispatchtouchevent passed to the child element.

Return super.dispathertouchevent: events will not be intercepted by default.

Summary: calling in dispatchtouchevent, as the name suggests, is to judge whether to intercept an event. (Note: only ViewGroup has a method. View does not need and does not have this method because it has no child view.). Moreover, this event sequence (current and other events) can only be processed by the ViewGroup, and the onintercepttuchevent method will not be called to ask whether to intercept.

Return true: event consumption. The current event terminates.

Return false: ontouchevent given to the parent view.

Return super.dispathertouchevent: the default logic for handling events is the same as when false is returned.

Summary: called inside dispatchtouchevent

The calling relationship between the above three methods can be represented by the following code:

For a click event, the activity will first receive the notification of the event, and then pass it to the decorview (root view). The decorview will pass the event level by level. The specific transfer logic is shown in the figure below:

It can be seen that the event transfer process is from the parent view to the child view. If it is not handled, it will eventually be handled by the activity. But here are three points that need special emphasis

Start with the dispatchtouchevent method in the activity:

The activity passes the event to the parent activity for processing. Let's see how the parent activity handles it.

There is an onuserinteraction method. This method will respond as long as the user clicks or slides anywhere in the activity. It is generally not used. Next, let's look at the specific meaning represented by getwindow(). Superdispatchtouchevent (EV). Getwindow() returns the window of the corresponding activity. An activity corresponds to a window, that is, a phonewindow. A phonewindow holds an instance of a decorview. The decorview itself is a FrameLayout. This sentence must be kept in mind.

The only existing implementation of this abstract class is android.view.phonewindow. The only implementation class of window is phonewindow. Then look at the code corresponding to phonewindow.

Phonewindow calls the superdispatchtouchevent method of decorview again. The decorview is the root view of the window, and the view we set through setcontentview is its child view (the setcontentview of the activity finally calls the setcontentview of phonewindow)

Here, the event has been passed to the root view, which is actually a ViewGroup. So how are events passed in the ViewGroup?

First look at the code marked in red. This sentence means: when action_ When the down event arrives, or a child element handles the event (mfirsttouchtarget! = null). If the child view does not call requestdisallowinterceptouchevent to prevent the interception of ViewGroup, the oninterceptouchevent of ViewGroup will be called to judge whether to intercept. Therefore, when the child view does not let the parent view intercept events, it is useless even if the parent view returns true in onintercepttouchevent.

Note that onintercepttouchevent returns false by default. When action_ When the down event arrives, the mfirsttouchtarget is null, and the child view requestdisallowintercepttouchevent has not been received yet. So at this time, as long as the parent view puts the action_ If the down event is intercepted, the child view will not receive any event messages. Therefore, generally in action_ When down, the parent view does not intercept.

When action_ When a move event comes, when certain conditions are met and the parent view wants to intercept, the child view can act in the dispatchtouchevent_ When the down event comes, call requestdisallowintercepttouchevent to avoid being intercepted by the parent view.

FLAG_ DISALLOW_ The interrupt flag bit is set through the child view requestdisallowintercepttouchevent method. See the following code for details.

At the same time, if the ViewGroup has a parent view, the parent view must not be intercepted. Continue to look at the dispatchtouchevent method of ViewGroup.

The above is the distribution of events by ViewGroup. There are two main points

Dispatchtouchevent() returns true only if the following three conditions are true in the above method; Otherwise, execute ontouchevent ().

This means that if setontouchlistener is called and listener is set, the ontouch method will be called first. If not, the ontouchevent method will be called. Next, let's look at the ontouchevent source code.

From the above code, we can know that when the finger is raised, it is in motionevent.action_ Up, performclick() will be called. The onclick method is called in performclick.

This means that the priority of the three is ontouch - > ontouchevent - > onclick

So far, the event distribution mechanism of view has been explained.

Causes of sliding conflict: as long as there are internal and external layers in the interface that can slide at the same time, sliding conflict will occur. As shown below: Figure 1 shows the left-right sliding conflict and up-down sliding conflict, and Figure 2 shows the up-down sliding conflict between two views;

Solution: judge who needs to respond to the sliding event according to the actual situation.

There are two main solutions, one is the external interception method, the other is the internal interception method.

You can see from the title that the external interception method is to solve sliding conflicts through the parent view. Because the parent view must belong to the ViewGroup, the parent view determines whether to intercept events according to its own needs. For ViewGroup, there is an onintercepttouchevent method. When interception is needed again, it can return true.

Since the external interception method is that the sub view actively handles the interception, the internal interception method requires the sub view to handle the sliding conflict. So how should the sub view be handled? First, the child view calls requestdisallowintercepttouchevent inside the dispatchtouchevent method to prevent the parent view from intercepting events, and then handles the situations that need to be intercepted in the ontouchevent method. If it is not intercepted, return false and return the event to the parent view for processing.

At the same time, in order to avoid the consumption event of the parent view, the parent view will not be intercepted when the down event comes, otherwise the event will not be transmitted to the child view.

If the child view does not process the event, the parent view will obtain the permission to process the event again.

1. Event distribution mechanism and sliding conflict resolution of Android view

2. Read the Android view event distribution mechanism

3. Detailed explanation of Android event distribution mechanism: the most comprehensive and understandable in history

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>