Android UI Interface Architecture
Each activity contains an PhoneWindow
object that PhoneWindow
is set DecorView
to the root view of the application window. In the inside is familiar TitleView
and ContentView
, yes, usually use setContentView()
is set ContentView
.
How does Android draw a view?
When an activity is started, it is asked to plot its layout. The Android framework handles this request, of course, provided the activity provides a reasonable layout. Drawing starts from the root view, traversing the entire view tree from top to bottom, each ViewGroup
responsible for making its own children View
drawn, View
each one responsible for drawing himself, through the draw()
method. The drawing process takes three steps.
The entire drawing process is ViewRoot
expanded in the performTraversals()
method. Some of the source code is as follows:
private void Performtraversals () {... // // lp.width and Lp.height when creating ViewGroup instances equals Match_parent int childwidthmeasurespec = Getrootmeasurespec (Mwidth, Lp.width); int childheightmeasurespec = 0, 0
Be sure to know the size and drawing of the view before drawing. So first proceed measu
and layout
(Measurement and positioning). such as:
Measure Process
Public Final void measure (intint heightmeasurespec) { //.... // callback Onmeasure () method onmeasure (Widthmeasurespec, heightmeasurespec); // }
exactly calculates the actual size of the view, obtains a high width deposit mMeasuredHeight
and mMeasureWidth
, measure(int, int)
two parameters passed in. MeasureSpec
is a 32-bit int value, the height of 2 bits is the measured mode, and the low 30 bits are the measured size. The measurement mode can be divided into the following three kinds.
-
The exact value mode, when layout_width
or layout_height
specified as a specific value, or match_parent
, when the system uses exactly.
At_most maximum mode, wrap_content
when specified, the size of the control cannot exceed the maximum size allowed by the parent control.
UNSPECIFIED does not specify the measurement mode, the view wants how big is big, generally does not use very much.
According to the above source, the measure method cannot be rewritten, and the method that needs to be rewritten when customizing onMeasure
protected void onmeasure (intint heightmeasurespec) { setmeasureddimension ( Getdefaultsize (Getsuggestedminimumwidth (), Widthmeasurespec), getdefaultsize (Getsuggestedminimumheight (), Heightmeasurespec)); }
See the source of the final aspect is called setMeasuredDimension()
set, if not overridden, is called directly by default getDefaultSize
Gets the size of the.
Use view's getmeasuredwidth() and getmeasuredheight() methods to get the width of the view measurement, These two methods must be guaranteed to be called after the onmeasure process to return a valid value.
Layout process
The layout method is used to determine the location of the view layout, as if you know the size of a thing, always need to know the position to draw up.
mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
Layout gets four parameters, left, top, right, and bottom coordinates, relative to the parent view. As you can see here, the width and height of the just measurement are used.
Public voidLayoutintLintTintRintb) {intOLDL =Mleft; intOldt =Mtop; intOldb =Mbottom; intOldr =Mright; BooleanChanged =setframe (L, T, R, b); if(Changed | | (Mprivateflags & layout_required) = =layout_required) {... onlayout (changed, L, T, R, b); .....}
when layout is over getWidth()
with the getHeight()
the correct value is returned. by setFrame
Setting the coordinates. If the coordinates have changed, reposition them again. If it is a View object, then OnLayout is an empty method. Because the positioning is determined by viewgroup.
There's a problem here, and getWidth/Height()
getMeasuredWidth/Height()
What's the difference?
getWidth()
: The width of the view after setting the layout.
getMeasuredWidth()
: The width of the view content that is measured after the content on the view
Draw Process
1 Public voidDraw (canvas canvas) {2 ......3 /*4 * Draw traversal performs several drawing steps which must be executed5 * In the appropriate order:6 *7 * 1. Draw the background8 * 2. If necessary, save the canvas ' layers to prepare for fading9 * 3. Draw View ' s contentTen * 4. Draw Children One * 5. If necessary, draw the fading edges and restore layers A * 6. Draw Decorations (scrollbars for instance) - */ - the //Step 1, draw the background, if needed - ...... - if(!Dirtyopaque) { - drawbackground (canvas); + } - + //Skip Step 2 & 5 if possible (common case) A ...... at - //Step 2, save the canvas ' layers - ...... - if(drawtop) { -Canvas.savelayer (left, top, right, top + length,NULL, flags); - } in ...... - to //Step 3, draw the content + if(!dirtyopaque) OnDraw (canvas); - the //Step 4, draw the children * Dispatchdraw (canvas); $ Panax Notoginseng //Step 5, draw the fade effect and restore layers - ...... the if(drawtop) { +Matrix.setscale (1, Fadeheight *topfadestrength); A Matrix.posttranslate (left, top); the Fade.setlocalmatrix (matrix); + P.setshader (Fade); -Canvas.drawrect (left, top, right, top +length, p); $ } $ ...... - - //Step 6, Draw decorations (scrollbars) the ondrawscrollbars (canvas); - ......Wuyi}
The point is that the third step calls the OnDraw method. The other steps are to draw some side corners of things such as backgrounds, ScrollBar and the like. Where it dispatchDraw
is used to recursively call the child view, if none is not required.
The OnDraw method needs to be implemented by itself, because each control paints a different content. It is mainly drawn with canvas objects.
Simply understand what the view is?