View layout and Drawing Mechanism in Android
To study the layout and Drawing Mechanism of the View in Android, I created a very simple App with only one Activity. The layout corresponding to the Activity is as follows:
The layout file is very simple. There is a TextView under RelativeLayout.
After the App is started, view the layout level in the App through Hierarchy Viewer, as shown below:
We can see that the root node of the App isPhoneWindow $ DecZ success? Http://www.bkjia.com/kf/ware/vc/ "target =" _ blank "class =" keylink "> vclZpZXc8L2NvZGU + release/release + 0tTJz8zhtb21xL/release + release + 2 + M/Cv6rKvLbUy/release + release/release + 2 + M/CttTL + release/release + dPQVmlld7XEwb/L47mk1/release + zdaqtcDBy8O/release/ 2Lz + signature/nT0FZpZXe9 + NDQu + bNvKOs1eLR + UFuZHJvaWS + zb2ry/nT0LXEVmlld + signature + Signature = ""> traffic Calculation
About Measure:
View uses the measure () method to calculate the size. The purpose of the calculation is to let the parent node know the size of the View, so the volume is the basis for layout and drawing of the View.
The onMeasure () method is executed in the measure () method of View, and the onMeasure () method of View class itselfNoEmpty method, which saves the result of the calculation to the View. The subclass of View should not overwrite the measure () method. If necessary, rewrite the onMeasure () method. The subclass of ViewGroup should overwrite the onMeasure () method, for examplePhoneWindow$DecorView
, RelativeLayout, FrameLayout, and RelativeLayout all override the onMeasure () method. All these classes traverse the child in the onMeasure () method, call the child's measure () method, and perform a volume calculation on the child, perform vertical recursion to calculate the number of View trees from top to bottom until the number of views on the leaf node is calculated.
The starting point of the quantitative calculation is the ViewRootImpl class, And ViewRootImpl is the root View, that is, the root node on the View tree. Strictly speaking, ViewRootImpl does not belong to the View, and it implements the ViewParent interface.PhoneWindow$DecorView
.
Android uses the depth-first algorithm instead of the breadth-first algorithm for top-down statistics on The View tree, that is, when traversing a View, android first traverses the View vertically and calculates the View on the leaf node. Only after the View and all its child views (if any child views exist) are calculated, to calculate the View of the sibling node of the View.
The following is the calling process of Android for top-down views:
We can see from the above that ViewRootImpl executes the doTraversal () and javasmtraversals () methods first, and then executes the performMeasure () method of ViewRootImpl, which is the starting point for Android to calculate all views. In this method, the View tree is traversed from the ViewRootImpl. FirstPhoneWindow$DecorView
InPhoneWindow$DecorView
When the onMeasure () method of is used, it traverses all the child and calculates the quantity of them in sequence. First, it calls the LinearLayout's measure () method and calculates the quantity of the first child node LinearLayout.
LinearLayout calls the onMeasure () method in the measure () method. In this method, LinearLayout calls the measureVertical () method, which traverses its child and calculates its quantity, because its child node ViewStub is not used for rendering, we do not calculate its quantity here. we ignore it and perform a quantitative calculation on the other child FrameLayout to call the measure () method of FrameLayout.
FrameLayout will execute the onMeasure () method when executing the measure () method. In this method, all the children will be traversed and Their counts will be calculated. There is only one child, that is, RelativeLayout. Call the measure () method of RelativeLayout to calculate its quantity.
RelativeLayout in the measure () method, the onMeasure () method is executed. In this method, all the children are traversed and Their counts are calculated. There is only one child, that is, TextView. Call the measure () method of TextView to calculate the quantity, and the onMeasure () method is executed.
The above completes the calculation of LinearLayout and all its subcalculation views in the View tree.PhoneWindow$DecorView
The other two views in maxcompute also reflect the process in which Android uses the depth-first algorithm to traverse the View tree. View @ 49da0d3 and View @ 44ff410 execute the measure () method and onMeasure () method in sequence.
In this way, the top-down calculation process of the View tree is over. After calculation, Android knows the size of each View to be rendered, that is, the width and height information.
For details about the measure () and onMeasure () methods in quantitative calculation, we will also write a blog introduction.
LayoutAbout Layout:
The premise of the layout is that the View has been calculated. The View is laid out by calling the layout () method. The layout aims to let Android know the position of the View in its parent control, that is, the Distance left, right, top, and bottom from the four sides of the parent control. The layout is the basis of the drawing. Only after the layout is completed can the View be drawn.
The onLayout () method is executed in the layout () method of the View, and the onLayout () method of the View class itself is an empty method. The View subclass should not override the layout () method. If necessary, rewrite the onLayout () method. The subclass of ViewGroup should override the onLayout () method, for example, PhoneWindow $ DecorView, RelativeLayout, FrameLayout, and RelativeLayout all overwrite the onLayout () method. These classes traverse child in the onLayout () method and call the child layout () method, child layout, vertical recursion, to achieve top-down layout of the View tree until the layout of the View on the leaf node is completed.
The starting point of the layout is also the ViewRootImpl class. ViewRootImpl is the root View, that is, the root node on the View tree. Strictly speaking, ViewRootImpl does not belong to the View and implements the ViewParent interface.PhoneWindow$DecorView
.
Android uses the depth-first algorithm instead of the breadth-first algorithm for top-down layout of the View tree, that is, when traversing a View, android will first traverse the View vertically and layout it to the View on the leaf node. Only after the layout of the View and all its child views (if any child views exist) is completed, view of the sibling node of the View.
The layout process in Android is similar to the preceding calculation process. The following is the calling process of Android for top-down layout of all views:
From the above we can see that ViewRootImpl first executes the doTraversal () and javasmtraversals () methods, and then executes the javasmlayout () method of ViewRootImpl, which is the starting point for Android to layout all views. In this method, the View tree is traversed from the ViewRootImpl to the top-down, and the ViewRootImpl is executed first.PhoneWindow$DecorView
Layout () method to deploy it.
PhoneWindow$DecorView
In its layout () method, the onLayout () method is executed,PhoneWindow$DecorView
The onLayout () method traverses all its children and calls the child layout () method in sequence to layout the child. Call the layout () method of the first child LinearLayout.
LinearLayout runs the onLayout () method in the layout () method. In this method, the layoutVertical () method is called, this method traverses all its child and calls the child layout () method in turn to layout. Because its child node ViewStub is not used for rendering, we will not layout it here, ignore it, layout another child FrameLayout, and call the layout () method of FrameLayout.
FrameLayout will execute the onLayout () method in the layout () method. In this method, the layoutChildren () method will be called, this method traverses all its child and calls the child layout () method in turn to layout. There is only one child, that is, RelativeLayout. Execute the layout () method of RelativeLayout to layout it.
RelativeLayout in the layout () method, the onLayout () method is executed. In this method, all the children are traversed and the child layout () method is called in sequence for layout. There is only one child, that is, TextView. Call the layout () method of TextView to layout it. The onLayout () method is executed.
The layout of LinearLayout and all its child views in the View tree is completed.PhoneWindow$DecorView
The layout of the other two views also reflects the process in which Android uses the depth-first algorithm to traverse the View tree layout. View @ 49da043 and View @ 44ff410 execute the layout () method and onLayout () method in sequence.
In this way, the entire top-down layout of the View tree ends. After layout, Android knows the position of each View in its parent control.
PlottingAbout Draw:
The premise of drawing is that the View has been computed and laid out. The View is drawn by calling the draw () method. The purpose of drawing is to display the View on the UI interface.
In the draw () method of View, the onDraw () and dispatchDraw () methods are sequential. The onDraw () and dispatchDraw () Methods of View classes are empty. The View subclass should not override the draw () method. If necessary, you should choose to override the onDraw () method or the dispatchDraw () method as needed. Specifically:
When we need to customize a View (rather than a ViewGroup), we need to override the onDraw () method of the View to draw the custom View, that is, onDraw () used to draw the View UI. The ViewGroup class in Android overrides the dispatchDraw () method in the View, ViewGroup. the dispatchDraw () method traverses all its children and calls the child's draw () method in sequence, that is, dispatchDraw () is used to draw the UI of all child views of the ViewGroup () different. Because ViewGroup has implemented the dispatchDraw () method, in most cases, the ViewGroup subclass does not need to be rewritten, such as PhoneWindow $ DecorView, RelativeLayout, FrameLayout, and RelativeLayout.NoOverride the dispatchDraw () method. Only in rare cases can we rewrite the dispatchDraw () method of ViewGroup to meet certain special requirements. However, even if we rewrite this method, we should call super in our implementation. the dispatchDraw () method is used to draw child views.The starting point of the drawing is also the ViewRootImpl class. ViewRootImpl is the root View, that is, the root node on the View tree. Strictly speaking, ViewRootImpl does not belong to the View. It implements the ViewParent interface and PhoneWindow $ DecorView.
Android uses the depth-first algorithm instead of the breadth-first algorithm when drawing the View tree from top to bottom, android will first traverse the View along the portrait and draw it to the View on the leaf node. Only after the View and all its child views (if any child views exist) are drawn, to render the View's sibling node View.
The plotting process in Android is similar to the preceding calculation and layout process. The following is the calling process of Android for top-down plotting of all views:
From the above we can see that ViewRootImpl first executes the doTraversal () and javasmtraversals () methods, and then executes the export mdraw () method of ViewRootImpl, which is the starting point for Android to plot all views. In this method, the View tree is traversed from the ViewRootImpl to the top-down, and the ViewRootImpl is executed first.PhoneWindow$DecorView
The draw () method to plot it.
PhoneWindow$DecorView
In its draw () method, the onDraw () method and the dispatchDraw () method are executed sequentially. In the dispatchDraw () method, all child data is traversed and the child's draw () method is called, graph child. Call the draw () method of the first child LinearLayout.
LinearLayout will also execute the onDraw () method and dispatchDraw () method in sequence in the darw () method. In the dispatchDraw () method, it will traverse all the child and call the child's draw () method, graph child. Because its child node ViewStub is not used for rendering, we will not plot it here, ignore it, plot another child FrameLayout, and call the draw () method of FrameLayout.
FrameLayout also executes the onDraw () method and dispatchDraw () method in sequence in the draw () method. In the dispatchDraw () method, it traverses all the children and calls the child's draw () method, graph child. There is only one child, that is, RelativeLayout. Execute the draw () method of RelativeLayout to plot it.
RelativeLayout also executes the onDraw () method and dispatchDraw () method in sequence in the draw () method. In the dispatchDraw () method, it traverses all the children and calls the child's draw () method, graph child. There is only one child, that is, TextView. Execute the draw () method of TextView to draw the TextView, and execute the onDraw () method of TextView to render the TextView.
The preceding figure shows how to plot the LinearLayout and all its child views in the View tree.PhoneWindow$DecorView
The other two views are used for plotting, which also reflects the process of traversing the View tree using the depth Priority Algorithm in Android. View @ 49da043 and View @ 44ff410 execute the draw () method and onDraw () method in sequence.
SummaryWhen we call the onCreate () methodsetContentView(R.layout.activity_main)
After the method, Android calculates, layout, and draws all views from top to bottom in the tree structure of layout:
The start point of calculation, layout, and drawing is ViewRootImpl.
By calling the performMeasure () method of ViewRootImpl, Android starts to calculate all views from top to bottom, so that Android knows the size of each View, that is, the width and height information.
After the calculation of all views is completed, the Android system will start to drive the layout of all views from top to bottom by calling the lateral mlayout () method of ViewRootImpl, android knows the position of each View in its parent control, that is, the left, right, top, and bottom
After the layout of all views is completed, Android starts to draw all views from top to bottom by calling the lateral mdraw () method of ViewRootImpl, in this way, Android renders all views to the screen.
I hope this article will help you understand the layout and Drawing Mechanism of the View in Android.