Comprehensive analysis of Android view drawing process

preface

In the previous articles, the author described the decorview, measure and layout processes respectively. Next, the last process of the three workflow - drawing process will be analyzed in detail. The measurement process determines the size of the view, and the layout process determines the position of the view. The drawing process will determine the appearance of the view. What a view should display is completed by the drawing process. The following source codes are taken from Android API 21.

Start with performdraw

As mentioned in the previous articles, the three workflow processes begin with viewrootimpl#performtraversals. Within this method, performmeasure, performlayout and performdraw will be called to complete the measurement, layout and drawing processes respectively. Let's start with the performdraw method. Viewrootimpl#performdraw:

The viewrootimpl#draw method is called and the fullredrawneeded parameter is passed. This parameter is obtained from the mfullredrawneeded member variable. It is used to judge whether all views need to be redrawn. If the view is drawn for the first time, it is obvious that the view should be drawn. If the view is redrawed for some reason, Then it is not necessary to draw all views. Let's take a look at viewrootimpl#draw:

Some codes are omitted here. We only look at the key codes. First, we obtain the mdirty value, which saves the information of the area to be redrawn. There will be a special article on view redrawing later. Let's get familiar with it first. Then, according to fullRedrawNeeded, we can decide whether we need to reset the dirty area. Finally we call the ViewRootImpl#drawSoftware method and pass the relevant parameters into it, including the dirty area.

You can read books, first of all, instantiate the Canvas object, then lock the area of the canvas, decide by the dirty area, then make a series of attribute assignments to canvas, and finally call the mView.draw (canvas) method. In the previous analysis, mView is DecorView, that is to say, starting from DecorView, all the work done before is preparatory work. Now it is the formal beginning of the drawing process.

Drawing of view

Since the ViewGroup does not override the draw method, all views call the view #draw method. Therefore, we can directly look at its source code:

It can be seen that the draw process is complex, but the logic is very clear, and the official notes clearly explain the practice of each step. Let's first look at the initial flag bit dirtyopaque, which is used to judge whether the current view is transparent. If the view is transparent, we can see from the following logic that some steps will not be performed, such as drawing background, drawing content, etc. This is easy to understand, because since a view is transparent, there is no need to draw it. Then there are the six steps of the drawing process. Here we summarize what these six steps are respectively, and then expand.

Six steps of the drawing process: 1. Draw the background of the view 2. Save the current layer information (skippable) 3. Draw the content of the view 4. Draw the sub view of the view (if there is a sub view) 5. Draw the faded edge of the view, similar to the shadow effect (skippable) 6. Draw the decoration of the view (e.g. scroll bar), of which step 2 and step 5 can be skipped, We don't do analysis here. We focus on other steps.

Skip 1: draw background

The view #drawbackground method is called here. Let's look at its source code:

It can be seen that the offset parameters of the view, scrollx and scrolly, are considered here, and the drawing background is drawn in the offset view.

Skip 3: drawing content

Here, the view #ondraw method is called. This method is an empty implementation in the view. Because different views have different contents, we need to implement it ourselves, that is, rewrite this method in the custom view to implement it.

Skip 4: drawing subviews

If the current view is a ViewGroup type, you need to draw its child views. Dispatchdraw is called here, and the method in the view is empty. In fact, ViewGroup overrides this method. Let's take a look. Viewgroup#dispatchdraw:

The source code is very long. Here is a brief description. It mainly traverses all sub views. Each sub view calls the drawchild method. We find this method, viewgroup#drawchild:

It can be seen that the draw method of view is called here, but this method is not as mentioned above. Because the parameters are different, let's take a look at this method. View#draw:

Let's focus on the core part. First, judge whether there is a cache, that is, whether it has been drawn once before. If not, call the draw (canvas) method to start normal drawing, that is, the six steps mentioned above. Otherwise, use the cache to display. This step can also be summarized as the ViewGroup drawing process, which draws the sub view, and the sub view will call its own draw method to draw itself. In this way, the sub view and the sub view will continue to draw themselves, so as to complete the drawing of the view tree.

Skip 6 draw decoration

The so-called drawing decoration refers to the rest of the view except the background, content and sub view, such as the scroll bar. Let's look at view #ondrawforegroup:

It can be seen that the logic is very clear, which is very similar to the general drawing process. The drawing area is set first, and then the canvas is used for drawing. It will not be expanded here. Those who are interested can continue to understand.

So far, the drawing process of view has been described. I hope this article will help you. Thank you for reading.

Read more about Android view measurement process (measure) comprehensive analysis Android view layout process (layout) comprehensive analysis

The above is the whole content of this article. I hope it will be helpful to your study, and I hope you can support programming tips.

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