introduce The workflow of View mainly refers to the three major processes of measure, layout and draw, i.e., measure determines the measured width and height of View, layout determines the positions of the four vertices of View in its parent View according to the measured width and height, and draw draws View to the screen, so that through the recursive traversal of ViewGroup, a View tree is displayed on the screen. It is simple to say, let's analyze it step by step from the source code: Android's View is a tree structure: Basic Concepts Before introducing the three major processes of View, we must first introduce some basic concepts to better understand the whole process. The concept of Window Window represents the concept of a window, which is an abstract concept from the perspective of WindowManagerService. All views in Android are presented through Windows, whether it is Activity, Dialog or Toast, as long as there is a View, there must be a Window. It should be noted here that this abstract Window concept is not the same as the PhoneWindow class. PhoneWindow represents the abstraction of the mobile phone screen. It acts as a medium between Activity and DecorView. Even if there is no PhoneWindow, View can be displayed. Putting everything aside, from the perspective of WindowManagerService alone, the Android interface is displayed by stacking windows, and Window is an abstract concept. It does not actually exist. It exists in the form of View, and this View is DecorView. Regarding Window, let's first understand a general Concept of DecorView DecorView is the top-level View of the entire Window interface. The measurement, layout, drawing, and event distribution of the View are all done by DecorView traversing the View tree downwards. As the top-level View, DecorView generally contains a vertical LinearLayout inside. There are two parts in this LinearLayout (the specific situation depends on the Android version and theme), the upper part is the [title bar], and the lower part is the [content bar]. In the Activity, the layout file we set through setContentView is actually loaded into the [content bar], and the id of the content bar is content, so the method to specify the layout is called setContent(). The concept of ViewRoot ViewRoot corresponds to the ViewRootImpl class, which is the link between WindowManager and DecorView. The three major processes of View are all completed through ViewRoot. In ActivityThread, when the Activity object is created, DecorView will be added to Window, and the corresponding ViewRootImpl will be created at the same time, and the ViewRootImpl and DecorView will be associated and saved in the WindowManagerGlobal object.
Java The drawing process of View starts from the performTraversals method of ViewRoot. It goes through three processes: measure, layout, and draw to finally draw a View. The general process is as follows: Measure In order to better understand the measurement process of View, we also need to understand MeasureSpec, which is an internal class of View and represents the measurement specifications of View. MeasureSpec represents a 32-bit int value, the upper 2 bits represent SpecMode (measurement mode), and the lower 30 bits represent SpecSize (measurement size). Let's take a look at its specific implementation:
Java MeasureSpec avoids excessive object memory allocation by packing SpecMode and SpecSize into an int value and provides packing and unpacking methods. There are three types of SpecMode, each with a special meaning: UNSPECIFIED The parent container does not impose any restrictions on the View. It can be as large as required. This situation is generally used within the system to indicate a measurement state. EXACTLY The parent container has detected the exact size required by the View, and the final size of the View is the value specified by SpecSize. It corresponds to the two modes of match_parent and specific values in LayoutParams. AT_MOST The parent container specifies an available size, SpecSize, and the size of the View cannot be larger than this value. The specific value depends on the specific implementation of different Views. It corresponds to wrap_content in LayoutParams. The MeasureSpec of a View is determined by the MeasureSpec of its parent container and its own LayoutParams, but it is a little different for DecorView because it has no parent class. The following code in the measureHierarchy method in ViewRootImpl shows the creation process of DecorView's MeasureSpec, where desiredWindowWidth and desireWindowHeight are the screen sizes: ViewGroup measure
Java Let's take a look at the getRootMeasureSpec method:
Java Through the above code, the generation process of DecorView's MeasureSpec is very clear, because DecorView is a subclass of FrameLyaout and belongs to ViewGroup. For ViewGroup, in addition to completing its own measure process, it will also traverse and call the measure method of all child elements, and each child element will recursively execute this process. Unlike View, ViewGroup is an abstract class, and it does not override View's onMeasure method. This is easy to understand, because each specific ViewGroup implementation class has different functions, and how to measure should be decided by itself, such as LinearLayout and RelativeLayout. Therefore, it is necessary to traverse and measure the child View in the specific ViewGroup. Here we look at the measureChildWithMargins method provided in ViewGroup to measure the child View:
Java The above method will measure the child element. Before calling the child element's measure method, the child element's MeasureSpec will be obtained through the getChildMeasureSpec method. From the code, the creation of the child element's MeasureSpec is related to the parent container's MeasureSpec and its own LayoutParams, as well as the View's margin and the parent class's padding. Now let's take a look at the specific implementation of getChildMeasureSpec:
Java The above code creates the MeasureSpec of the child element based on the MeasureSpec of the parent class and its own LayoutParams. The specific process is analyzed by the students themselves. The final creation rules are as follows: After traversing the child Views, ViewGroup needs to determine its final measured size based on the measurement results of the child elements and call the setMeasuredDimension method to save the measured width and height values.
Java resolveSizeAndState is called here to determine the final size, mainly to ensure that the measured size does not exceed the maximum remaining space maxWidth of the parent container. Here we look at its implementation:
Java The onMeasure process of specific ViewGroup is not analyzed here. Since the measurement method of each layout is different, it is impossible to analyze them one by one, but the steps in their onMeasure are regular: 1. Traverse the Children elements according to their respective measurement rules and call the getChildMeasureSpec method to get the measureSpec of the Child; 2. Call Child's measure method; 3. Call setMeasuredDimension to determine the final size. View measure The measure process of View is completed by its measure method. The measure method is a final type method, which means that subclasses cannot override this method. The onMeasure method will be called in the measure method of View. Here we only need to look at the implementation of onMeasure, as follows:
Java The code is very simple. Let's continue to look at the implementation of the getDefaultSize method:
Java From the above code, we can conclude that the width/height of View is determined by specSize. Custom controls that directly inherit View need to override the onMeasure method and set their own size when wrap_content is used. Otherwise, using wrap_content in the layout is equivalent to using match_parent. The above is the general process of View measurement. After the measurement is completed, the measured width and height can be obtained through the getMeasuredWidth/Height method. This width and height is generally equal to the final width and height of the View, because the width and height of the View are set according to measureWidth/Height when the View is laid out, unless the measure value is modified in the layout. Layout The role of Layout is that ViewGroup is used to determine the position of child elements. When the position of ViewGroup is determined, it will traverse all child elements in onLayout and call their layout methods. In simple terms, the layout method determines the position of the View itself, while the onLayout method determines the positions of all child elements. Let's first look at the layout method of View:
Due to WeChat word limit, please click the original link to view the full content Summarize At this point, the three major processes of View measure, layout, and draw have been discussed. Here is a summary:
|
<<: Why are you forced to insert ads? Talking about HTTPS connections
Parents are always very concerned about their chi...
(1). It seems that your keyword quality is less t...
If operators or creators want their content to at...
According to a recent report by Shanghai Daily, t...
The original intention of globalization strategy ...
"Mental patients are all different and come ...
In response to the epidemic, the Chinese mobile p...
"The BA.5 strain is not only the most contag...
As spring comes and flowers bloom, marketing in v...
Think back, you must still remember several parti...
Recently, there has been a lot of good news in th...
At 9:00 a.m. on May 30, the Shenzhou 16 manned sp...
A few days ago, someone asked me in the backgroun...
In July this year, Zoe, who lives in Florida, USA...
Just as KOL corresponds to the herd effect in psy...