Original address: http://blog.csdn.net/guolin_blog/article/details/9153747
I remember in the previous article, I took you together from the source point of view of the analysis. Android In view of the event distribution mechanism, I believe that friends who have read the event distribution of View already have a deep understanding.
If you haven't read it yet, please refer to it first. The Android Event Distribution Mechanism is fully parsed to give you a thorough understanding of the source code perspective (I) .
So today we'll continue with the last unfinished topic, analyzing event distribution of ViewGroup from the source point of view.
First, let's talk about what is ViewGroup? What's the difference between it and ordinary View?
As the name implies, ViewGroup is a set of Views. It contains many sub-Views and sub-VewGroup. It is the parent or indirect parent of all layouts in Android. Linear Layout, Relative Layout, etc. are inherited from ViewGroup. But ViewGroup is also actually a View, except that it has more functions than View, including sub-Views and defining layout parameters. The view group inheritance schematic is as follows:
As you can see, the various layouts we often use in our usual projects are all subclasses 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, inherited from Linear Layout, as follows:
Then, open the main layout file activity_main.xml and add our custom layout to it:
As you can see, we added two buttons to MyLayout, and then registered listening events for both buttons and MyLayout in MainActivity:
We printed a sentence in MyLayout's onTouch method and Button1, Button2's onClick method. Now run the project, and the results are as follows:
Click on Button 1, Button 2 and the blank area, respectively. The print results are as follows:
You will find that MyLayout's registered onTouch method does not execute when the button is clicked, but only when the blank area is clicked. You can first understand that Button's onClick method consumes events, so events do not continue to pass down.
Does that mean that touch events in Android are passed to View and then to ViewGroup? It's too early to draw a conclusion. Let's do another experiment.
Looking at the documentation, you can see that there is an onInterceptTouchEvent method in ViewGroup. Let's look at the source code of this method:
If you don't look at the source code, you might be frightened by this comment. It's too long to read in English. But the source code is so simple! Only one line of code returns a false!
Well, since it's a Boolean return, there are only two possibilities. Let's rewrite this method in MyLayout and try returning a true. The code is as follows:
Now run the project again, and then Button 1, Button 2, and the blank area, respectively. The print results are as follows:
You will find that no matter where you click, it will always trigger the touch event of MyLayout. The click event of the button is completely blocked! Why is that? How can MyLayout block Button clicks if the touch event in Android is passed to View and then to ViewGroup?
It seems that only by reading the source code and understanding the event distribution mechanism of ViewGroup in Android can we solve our doubts, but I want to tell you first that the transmission of touch events in Android is definitely transmitted to ViewGroup first and then to View. Remember in The Android Event Distribution Mechanism is fully parsed to give you a thorough understanding of the source code perspective (I) As I explained, as long as you touch any control, you will call the dispatchTouchEvent method of the control. That's true, but it's not complete. In fact, when you click on a control, you first call the dispatchTouchEvent method of the layout of the control, then find the corresponding control clicked 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 MyLayout's dispatchTouchEvent method first, but you will find that MyLayout does not have this method. Then look in its parent class LinearLayout and find that there is no such method. So you have to continue looking for LinearLayout's parent ViewGroup. You finally see this method in the ViewGroup, where the dispatchTouchEvent method of the button is called. The revised schematic diagram is as follows:
So what are we waiting for? Take a look at the source code of the dispatchTouchEvent method in ViewGroup. The code is as follows:
This method has a long code, so we only focus on it. First, you can see a conditional judgment in line 13. If one of the disallow Intercept and! On Intercept TouchEvent (ev) is true, you will enter the conditional judgment. Disallow Intercept refers to whether the function of event interception is disabled, default is false, or this value can be modified by calling the request Disallow Intercept TouchEvent method. So when the first value is false, it depends entirely on the second value to decide whether it can enter the interior of conditional judgment. What is the second value? It's the reverse of the return value of the onInterceptTouchEvent method! That is to say, if we return false in the onInterceptTouchEvent method, we will let the second value be true, thus entering the interior of the conditional judgment. If we return true in the onInterceptTouchEvent method, we will let the second value be false, thus jumping out of the conditional judgment.
Now you can think about it. Since we just rewrote the onInterceptTouchEvent method in MyLayout to return to true, so that all button clicks are blocked, we have every reason to believe that the processing of button clicks is done within the 13-line condition judgment.
So let's focus on how the interior of conditional judgment is realized. In line 19, through a for loop, all the sub-Views under the current ViewGroup are traversed, and then in line 24, the view that is currently traversed is judged to be the View that is being clicked. If so, it goes inside the condition judgement. Then in line 29, the dispatch TouchEvent of the View is invoked, and the process follows. The Android Event Distribution Mechanism is fully parsed to give you a thorough understanding of the source code perspective (I) The explanation is the same. We also confirm that the processing of button click events is actually done here.
Next, you need to note that there is a return value after calling dispatchTouchEvent of the child View. We already know that if a control is clickable, the return value of dispatch TouchEvent must be true when clicking on the control. This results in the conditional judgment on line 29, so the dispatchTouchEvent method given to ViewGroup on line 31 returns true directly. This results in the failure of the following code to execute, and also confirms the result of Demo printing in front of us. If the click event of the button 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, instead of returning true on line 31, you will continue to execute the following code. So let's move on to line 44, and if the target equals null, it goes inside the condition judgment, where normally the target is null, so super. dispatch TouchEvent (ev) is called on line 50. Where will this code be called? Of course, it's the dispatchTouchEvent method in View, because the parent class of ViewGroup is View. The subsequent processing logic is the same as the previous one, so the onTouch method registered in MyLayout will be executed. After that, the code is generally not accessible, and we will not continue to analyze.
Take a look at the flow chart of the entire ViewGroup event distribution process, I believe it can help you better understand:
Now that the analysis of the event distribution process for the entire ViewGroup is over, let's just sort it out briefly.
1. Android event distribution is first passed to ViewGroup, and then from ViewGroup to View.
2. In ViewGroup, event delivery can be intercepted by onInterceptTouchEvent method. The onInterceptTouchEvent method returns true to deny event continuation to sub-View, false to deny event interception and false to default.
3. If the passed events are consumed in the sub-View, no events will be received in the ViewGroup.
Well, the Android event distribution mechanism is completely resolved to this end, combined with the next two articles, I believe you have a very deep understanding of event distribution.