Detailed explanation of Android view drawing mechanism

View rendering mechanism I

Drawing process of view tree

When the activity receives the focus, it will be requested to draw the layout, which is processed by the Android framework. Drawing is to measure and draw the layout tree from the root node. The drawing process of the entire view tree is expanded in the performtraversals() function of the viewroot.java class. The work done by this function can be summarized as whether to recalculate the view size, relocate the view layout, and redraw. The flow chart is as follows:

View drawing process function call chain

It should be noted that when the user actively calls Request, it will only start the measure and layout process, not execute the draw process

2、 Concept

1. Measure and layout

On the whole, the implementation of measure and layout steps:

The traversal of the tree is orderly, from the parent view to the child view. Each ViewGroup is responsible for mapping all its child views, and the bottom view is responsible for mapping itself.

2. Specific analysis

The measure process is initiated by the measure (int, int) method. The measurement views are ordered from top to bottom. At the end of the measure process, each view stores its own size and measurement specifications. The layout process is initiated by the layout (int, int, int) method and traversed from top to bottom. In this process, each parent view will place its own child views according to the size obtained in the measure process.

The measure procedure assigns values to the mmeasuredwidth and mmeasuredheight variables of a view and all child nodes, which can be obtained through the getmeasuredwidth () and getmeasuredheight () methods. Moreover, these two values must be within the constraints of the parent view, so as to ensure that all parent views receive the measurements of all child views. If the child view is not satisfied with the size obtained by the measure, the parent view will intervene and set the measurement rules for the second measure. For example, the parent view can measure each child view according to an unspecified dimension. If the unconstrained size of the final child view is too large or too small, the parent view will measure the child view again with an exact size.

3. The measure procedure passes two classes of dimensions

ViewGroup.LayoutParams

This class is very common. It is used to specify parameters such as the height and width of the view. For the height and width of each view, you have the following options:

The subclass of ViewGroup has its corresponding subclass of viewgroup.layoutparams. For example, relativelayoutparams, a subclass of viewgroup.layoutparams owned by relativelayout.

Sometimes we need to use the view. Getlayoutparams () method to obtain a view layoutparams and then perform forced conversion, but we may cause forced conversion errors because we don't know its specific type. In fact, what this method obtains is the layoutparams of its parent view type. For example, if the parent control of view is relativelayout, the obtained layoutparams type is relativelayoutparams.

MeasureSpecs

Measurement specifications, including information on measurement requirements and dimensions, have three modes:

UNSPECIFIED

The parent view does not have any constraints on the child view. It can reach any desired size. For example, listview and Scrollview are not commonly used in custom views,

EXACTLY

The parent view specifies an exact size for the child view, and no matter how large the child view is expected, it must be within the boundary of the specified size, and the corresponding attribute is match_ Parent or specific value, such as 100dp, the parent control can directly obtain the size of the child control through measurespec. GetSize (measurespec).

AT_ MOST

The parent view specifies a maximum size for the child view. The subview must ensure that all its own subviews can fit within the size range, and the corresponding attribute is wrap_ Content, in this mode, the parent control cannot determine the size of the child view, and the child control can only calculate its own size according to its own needs. This mode is the case where we need to implement measurement logic for our custom view.

3. Measure core method

Measure (int widthmeasurespec, int hightmeasurespec) this method is defined in the view.java class. It is of final type and cannot be copied. However, the measure call chain will eventually call back the onmeasure() method of the view / ViewGroup object. Therefore, when customizing the view, you only need to copy the onmeasure() method.

onMeasure(int widthMeasureSpec,int heightMeasureSpec)

This method is the method to implement the measurement logic in our custom view. The parameters of this method are the measurement requirements of the parent view for the width and height of the child view. In our own custom view, we need to calculate the width and height of the view according to the widmeasurespec and hightmeasurespec. Different modes have different processing methods.

setMeasuredDimension()

The final method in the measurement phase is called in the onMeasure (int widthMeasureSpec, int heightMeasureSpec) method, and the calculated size is passed to the method, and the measuring stage is finished. This method is also a method that must be called, otherwise an exception will be reported. When we customize the view, we don't need to care about the complex measurement process of the system. Just call setmeasureddimension() to set the size calculated according to measurespec. You can refer to the onmeasure method of viewpagerindicator.

Next, we take the measurechildren (int widthmeasurespec, int hightmeasurespec) method of ViewGroup to analyze the measurement process of composite view:

Method call flow chart of measurechild:

Source code analysis

4. Layout related concepts and core methods

First of all, the specific position of the child view is relative to the parent view. The onlayout method of view is null, while the onlayout of ViewGroup is abstract. Therefore, if a custom view wants to inherit ViewGroup, it must implement the onlayout function.

During the layout process, the child view will call the getmeasuredwidth () and getmeasuredheight () methods to obtain the mmmeasuredwidth and mmmeasuredheight obtained by the measure process as its own width and height. Then the layout (L, t, R, b) function of each subview is called to determine the location of each sub view in the parent view.

Analysis of onlayout source code of LinearLayout

5. Related concepts and core methods of drawing process

Let's first look at the functions related to the draw process:

View.draw(Canvas canvas):

Because ViewGroup does not duplicate this method, all views are finally drawn by calling the draw method of view. In a customized view, you should not copy this method, but copy the OnDraw (canvas) method for drawing. If the customized view really wants to copy this method, first call super.draw (canvas) to complete the system drawing, and then carry out customized drawing.

View.onDraw():

The OnDraw (canvas) of view is empty by default. The user-defined drawing process requires replication methods to draw its own content.

dispatchDraw()

Initiate the drawing of subviews. View is empty by default, and ViewGroup duplicates dispatchdraw() to draw its child views. We don't care about this method. The customized ViewGroup should not duplicate dispatchdraw().

Draw flow chart

View. Draw (canvas) source code analysis

From the above process, we can also get some optimization tips: when you don't need to draw a layer, step 2 and step 5 will be skipped. Therefore, when rendering, the layers that can be saved can be saved as much as possible, which can improve the rendering efficiency

Source code analysis of ViewGroup. Dispatchdraw()

drawChild(canvas,drawingTime)

The child. Draw (canvas, drawingtime) method of view is directly called. The document also states that you should not copy or call this method anywhere except by the ViewGroup. Drawchild () method. It belongs to ViewGroup. The view.draw (canvas) method is a method that can be copied in our custom control. For details, please refer to the above description of view.draw (canvas). As can be seen from the parameters, child. Draw (canvas, drawingtime) must handle the logic related to the parent view, but the final drawing of the view is still the view. Draw (canvas) method.

invalidate()

Request to redraw the view tree, that is, the draw process. If the size of the view does not change, the layout () process will not be called, and only those views that call the invalidate () method will be drawn.

requestLayout()

This method will be called when the layout changes, such as direction changes and size changes. In the customized view, if you want to re measure the size in some cases, you should call this method manually. It will trigger the measure () and layout () processes, but will not draw.

Thank you for reading, hope to help you, thank you for your support to this site!

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