Android thoroughly understands the analysis of event distribution mechanism from the perspective of source code (Part 2)

I remember in the previous article, I took you to analyze the event distribution mechanism of view in Android from the perspective of source code. I believe friends who have read have a deep understanding of view event distribution.

For those who haven't read it, please refer to Android to thoroughly understand the analysis of event distribution mechanism from the perspective of source code.

So today, we will continue the unfinished topic last time and analyze the event distribution of ViewGroup from the perspective of source code.

First, let's discuss what is ViewGroup? What is the difference between it and ordinary view?

As the name suggests, ViewGroup is a collection of views, which contains many child views and child vewgroups. It is the parent or indirect parent of all layouts in Android. For example, LinearLayout and relativelayout are inherited from ViewGroup. However, ViewGroup is actually a view, but it has more functions than view, including sub views and defining layout parameters. The schematic diagram of ViewGroup inheritance structure is as follows:

You can see that all the layouts we often use in projects belong to the subclass of ViewGroup.

After a brief introduction to ViewGroup, let's demonstrate the event distribution process of vewgroup in Android through a demo.

First, we define a layout, named mylayout, which inherits from LinearLayout, as follows:

Then, open the main layout file activity_ Main.xml and add our customized layout:

You can see that we have added two buttons in mylayout, and then registered listening events for these two buttons and mylayout in mainactivity:

We printed a sentence in the ontouch method of mylayout and the onclick methods of button1 and button2. Now run the following project, and the effect diagram is as follows:

Click button1, button2 and the blank area respectively, and the print results are as follows:

You will find that when you click the button, the ontouch method registered by mylayout will not be executed. It will only be executed when you click the blank area. You can first understand that the onclick method of the button consumes the event, so the event will not continue to pass down.

Does that mean that the touch event in Android is passed to view first and then to ViewGroup? It's too early to draw a conclusion now. Let's do another experiment.

Referring to the documentation, we can see that there is an onintercepttouchevent method in the ViewGroup. Let's take a look at the source code of this method:

If you don't look at the source code, you may be frightened by this annotation. Such a long English annotation makes you look big. But the source code is so simple! There is only one line of code and a false is returned!

Well, since it is a Boolean return, there are only two possibilities. Let's rewrite this method in mylayout and try to return a true. The code is as follows:

Now run the project again, and then respectively button1, button2 and the blank area. The print results are as follows:

You will find that no matter where you click, it will only trigger the touch event of mylayout, and the click event of the button is completely blocked! Why? If the touch event in Android is passed to view first and then to ViewGroup, how can mylayout mask the button click event?

It seems that only by reading the source code and understanding the event distribution mechanism of ViewGroup in Android can we solve our doubts. However, I want to tell you first that the transmission of touch events in Android is definitely transmitted to ViewGroup and then to view. I remember that in the analysis of Android's complete understanding of the event distribution mechanism from the perspective of source code, I explained that as long as you touch any control, you will call the dispatchtouchevent method of the control. That's right, but it's not complete. The actual situation is that when you click a control, you will first call the dispatchtouchevent method of the layout where the control is located, then find the clicked corresponding control in the dispatchtouchevent method of the layout, and then call the dispatchtouchevent method of the control. If we click the button in mylayout, we will call the dispatchtouchevent method of mylayout first, but you will find that there is no such method in mylayout. Then go to its parent class LinearLayout and find that there is no such method. Then you have to continue to find the parent class ViewGroup of LinearLayout. You finally see this method in ViewGroup. The dispatchtouchevent method of the button is called here. The modified schematic diagram is as follows:

What are you waiting for? Take a look at the source code of the dispatchtouchevent method in the ViewGroup! The code is as follows:

The code of this method is relatively long. We only focus on it. First, you can see a conditional judgment on line 13, if disallowaintercept and! If one of onintercepttuchevent (EV) is true, it will enter this condition judgment. Disallowintercept refers to whether the event interception function is disabled. The default value is false. This value can also be modified by calling the requestdisallowintercepttuchevent method. Then, when the first value is false, it will completely rely on the second value to determine whether it can enter the interior of condition judgment. What is the second value? It turns out that the return value of the onintercepttouchevent method is negated! In other words, if we return false in the onintercepttuchevent method, the second value will be true to enter the internal condition judgment. If we return true in the onintercepttuchevent method, the second value will be false to jump out of this condition judgment.

At this time, you can think about it. Because we have just rewritten the onintercepttouchevent method in mylayout to return true, resulting in all button click events being shielded, we have every reason to believe that the button click event is handled in the condition judgment in line 13!

Let's focus on how to realize the internal of conditional judgment. In line 19, through a for loop, traverse all sub views under the current ViewGroup, and then judge whether the currently traversed view is the view being clicked in line 24. If so, it will enter the internal part of the condition judgment, and then call the dispatchtouchevent of the view in line 29, The subsequent process is the same as that explained in the analysis of Android's complete understanding of the event distribution mechanism from the perspective of source code. Therefore, we have confirmed that the processing of button click events is indeed carried out here.

Then note that there is a return value after calling the dispatchtouchevent of the child view. We already know that if a control is clickable, the return value of dispatchtouchevent must be true when the control is clicked. Therefore, the condition judgment in line 29 is true, so the dispatchtouchevent method given to ViewGroup in line 31 directly returns true. In this way, the following code cannot be executed, which also confirms the results of our previous demo printing. If the button click event is executed, the touch event of mylayout will be intercepted.

What if we click on a blank area instead of a button? In this case, you will not return true on line 31, but continue to execute the following code. Let's continue to look back. In line 44, if the target is equal to null, it will enter the condition judgment. Generally, the target will be null, so super.dispatchtouchevent (EV) will be called in line 50. Where will this code call? Of course, it is the dispatchtouchevent method in view, because the parent class of ViewGroup is view. The subsequent processing logic is the same as that mentioned above, so the ontouch method registered in mylayout will be executed. In general, the subsequent code can't go, so we won't continue to analyze it.

Take another look at the flow chart of the whole ViewGroup event distribution process. I believe it can help you better understand:

Now the analysis of the whole event distribution process of ViewGroup is over. Let's briefly sort it out at last.

1. Android event distribution is delivered to ViewGroup first, and then to view by ViewGroup.

2. In the ViewGroup, you can intercept the event delivery through the onintercepttouchevent method. The onintercepttouchevent method returns true, which means that the event is not allowed to continue to be delivered to the child view. The return of false means that the event is not intercepted. The default is false.

3. If the passed events are consumed in the child view, the ViewGroup will not receive any events.

Well, this is the end of the complete analysis of Android event distribution mechanism. Combined with the previous and next articles, I believe you have a very deep understanding of event distribution.

The above is the whole content of this article. I hope it will be helpful to your study, and I hope you can support programming tips.

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
分享
二维码
< <上一篇
下一篇>>