Article Directory
View drawing process
Before drawing, the system will make some drawing preparations to create PhoneWindow, DecorView, ViewRootImpl. This process is in Activity's onCreate().
The drawing process of View starts with performTraversals() of the ViewRootImpl object
/**
* 源码分析:ViewRootImpl.performTraversals()
*/
private void performTraversals() {
// 1. 执行measure流程
// 内部会调用performMeasure()
measureHierarchy(host, lp, res,desiredWindowWidth, desiredWindowHeight);
// 2. 执行layout流程
performLayout(lp, mWidth, mHeight);
// 3. 执行draw流程
performDraw();
}
The View drawing process starts from the ViewGroup of the top-level View (DecorView), and traverses the mapping from the ViewGroup to the sub-View layer by layer: measure, layout, draw.
-
Starting from the root view, depth-first search traverses each sub-view to perform measure
-
Starting from the root view, a depth-first search traverses each child view to execute the layout
-
Starting from the root view, depth-first search traverses each child view to execute draw
Measure
The function of measure is to measure the width/height of View
In some cases, when the size of the view is affected by dynamic content, responsive design, layout constraints or animation effects, multiple measurements may be required to determine the final width or height, so the width/height obtained by the measure process may not be accurate,建议在layout过程中的onLayout去获取最终的宽 / 高。
The measure process of a single view:
- measure(): Judgment of basic measurement logic
- onMeasure(): divided into two steps
- getDefaultSize(): Calculate the width and height of the View according to the View width/height measurement specification
- setMeasure(): store the measured subview width/height
The measure process of ViewGroup:
注意:ViewGroup的measure过程中,等待所有的子view都measure完毕,合并所有子view的尺寸才可以得到ViewGroup父视图的测量值。
Layout
The function of the Layout process is to calculate the position of the view View, that is,
the four vertex positions of the View: Left, Top, Right and Bottom.
Draw
The function of the Draw process is to draw the View view.
A single View only needs to draw itself (including background, content) and decoration.
Note: decoration here refers to indicator, scrollbar and foreground
The drawing of ViewGroup includes:
- Self-drawing (with background and content)
- Traversing sub-Views, drawing one by one (background and content and decoration)
- Drawing decoration of ViewGroup
Steps to implement a custom View
Step 1: Implement Measure, Layout, Draw process
- From the View workflow (measure process, layout process, draw process), if you want to implement a custom View, depending on the type of custom View (single View / ViewGroup), you need to customize and implement different methods
- Mainly onMeasure(), onLayout(), onDraw(), as follows:
Custom Measure
ViewGroup.LayoutParams
The subclasses of ViewGroup (RelativeLayout, LinearLayout) have their corresponding ViewGroup.LayoutParams subclasses
Its role is to specify layout parameters such as the height and width of the view View.
Specifically, it is specified by the following parameters:
in the corresponding xml file:
android:layout_height="wrap_content" //自适应大小
android:layout_height="match_parent" //与父视图等高
android:layout_height="fill_parent" //与父视图等高
android:layout_height="100dip" //精确设置高度值为 100dip
MeasureSpec
MeasureSpec: Policy rule, which is composed of measurement mode (mode) and measurement size (size), a total of 32 bits (int type), of which mode occupies 2 bits and size occupies the lower 30 bits.
There are three measurement modes:
- UNSPECIFIED: The parent view does not constrain the child View, such as ListView, ScrollView, but generally custom View does not need this.
- EXACTLY: The parent view specifies an exact size for the child view, and the size of the child view must be this size. For example, match_parent, or specify a specific value of 100dp, in this mode, the measurement process of the view will ignore the layout parameters of the view (
LayoutParams
) - AT_MOST: The parent view specifies a maximum size for the child view, and the child view must ensure that itself and all child views can fit within this size. For example, wrap_content, adaptive size, the specific size is set according to requirements. In this mode, the parent control cannot determine the size of the child View, and can only design and calculate the size according to the needs of the child control itself.
The specific use of MeasureSpec:
The MeasureSpec class encapsulates the measurement mode (mode) and measurement size (size) with a variable: by using binary, the measurement mode (mode) and measurement size (size) are packaged into an int value, and the packaging is provided And the method of unpacking, this approach is to reduce object memory allocation and improve access efficiency. The specific use is as follows:
// 1. 获取测量模式(Mode)
int specMode = MeasureSpec.getMode(measureSpec)
// 2. 获取测量大小(Size)
int specSize = MeasureSpec.getSize(measureSpec)
// 3. 通过Mode 和 Size 生成新的SpecMode
int measureSpec=MeasureSpec.makeMeasureSpec(size, mode);
custom layout
The role of Layout is to calculate the four vertex positions of View: Left, Top, Right and Bottom
custom attributes
- Create custom attribute xml files in the values directory
- Load custom XML files & parse property values in the constructor of custom View
- Using custom attributes in layout files
drawing tools
Paint
Paint: Brush, its function is to determine the specific effect of the drawn content (such as color, size, etc.), and the brush is needed when drawing the content.
Specific use
step:
- Create a Paint object
- Set the brush, that is, the effect when drawing content, such as color and size
- Initialize the brush (try to choose the constructor in View)
Path
Canvas
Canvas: Canvas is a rule when drawing, and the drawing content is drawn on the screen according to the regulations of the canvas.