This article is from the Android Elite biography (Xu Yisheng)
I wrote here, I think Xu Yisheng is really good, but also added some of their own understanding, to facilitate their own foundation to improve.
If you want to draw a view, you need to take a measurement first, that is, you need to know its size and location. So we can slide it out of the screen. This process is done in the Onmeasure () method.
I. Measurement mode
When measuring the size of the view, you need to use the MEASURESPEC (measurement specification) class to specify the measurement mode, a total of 3
Exactly (exact mode), system default.
If we specify a control with a width height of xxdp, xxpx,match_parent (the size of the parent view), either of these 3 is the exact pattern.
At_most (max mode)
What do you mean by this maximum value? Confused for a long time, such as the parent control's child control (one or more), and the child control is warp_content, the size of the control will vary with the content of its child controls, at which point the child control's size does not exceed the maximum allowable size of the parent control.
For example, if the parent control specifies a size of 200, then we can take this value
result =N; if (Specmode = = measurespec.at_most) {= math.min (result, specsize);//Remove the minimum value of 2 if specsize (child control size) is greater than 200 of the parent control, use 200, otherwise use specsize}
UNSPECIFIED
This attribute is not used too much. --it does not specify its size measurement mode, how large the view is, and usually draws a custom view to use.
Two. When to use Onmeasure ()
The first thing to note is that this method does not have to be rewritten. The view class default Onmeasure () only supports exactly (precision) mode, and if the custom control is not overridden, it can only be used in exactly mode. The control can respond to the specific wide-height DP or PX or Match_parent property that you specify.
If you want custom view to support the Wrap_content property, you must override the Onmeasure method to specify the size of the warp_content.
By measurespec This class, we get the "measurement mode" of the view and the size that the view wants to draw. With this information, we can control the size of the view's final display.
First look at the method of Onmeasure ()
/** * Measure the size of the view * First This method is not required to be rewritten. ( You must override this method only if the control uses wrap_content) * When customizing view, Measurespec This measurement specification class, defines the 3 measurement specification: Exactly, at_most,unspecified * If we do not rewrite onmeasure (), the system default measurement specification is and can only be exactly * Override this method, you can use any one of the above 3 modes */ @Override protected void onmeasure (intint heightmeasurespec) { // The parent class Onmeasure internally calls Setmeasureddimension (wide, high) to fill in super with the width and height values measured by the final control . Onmeasure ( Widthmeasurespec, Heightmeasurespec); }
Three. Drawing of view
When measuring good one view, you can draw him. Drawing needs to be drawn in the OnDraw (canvas canvas) method, using the Canvas canvas class and the Paint brush class.
This method carries a canvas parameter, and we can create a paint object that can be drawn on the canvas. Of course, if the canvas is needed elsewhere, we will typically create a canvas canvas=new canvas (bitmap) alone.
/** * This construction method is commonly used when creating canvas canvases. Instead of a no-argument construction method. * Because this bitmap is used to store pixel information on canvas canvas. * This process is called loading the canvas, so after creating the canvas this way, all the canvas.drawxxx () are called later, and the methods are all on this bitmap. */ New Canvas (bitmap);
Four. Measurement of ViewGroup
ViewGroup, like LinearLayout it's going to manage its child view, and one of the management items is responsible for the display size of the internal sub-view. When the linearlayout size is warp_content, LinearLayout needs to traverse the child view to get the size of all the child view, thus determining its size. In other modes, you can set your own size by specifying a value.
LinearLayout The measure method of sub-view to obtain each sub-view measurement result by traversing all sub-view at the time of measurement. When the measurement is complete, the position of these sub-view will be placed, you need to rewrite the onlayout, the onlayout of the call sub-view to determine the sub-view location.
Note: When customizing ViewGroup, OnLayout is typically overridden to control the location of its child view display, and if a wrap_content property is required, you also need to override onmeasure () to measure the size of the child view.
Five. Drawing of ViewGroup
Normally viewgroup does not need to be drawn, because it is a container, itself is not good to draw, only it specifies the background color, will call its OnDraw, otherwise it will not be called. But ViewGroup uses the Dispatchdraw () method to draw its child view, Process and complete the drawing by traversing all child view and calling the OnDraw () method of the child view.
Six. Custom View
Several callback methods to be aware of when customizing view
Onfinishinflate () XML post-load callback
Onsizechanged () callback after size change
Onmeasure () Measure control size
OnLayout () Setting the control position
Ontouchevent () Control Touch Event
Customizing the view does not require rewriting all of the above callbacks, as needed.
Six. What is the use of custom view?
Extend to existing controls
Implementing new controls by combining them
Overriding view to implement a new control
6.1 Extending to existing controls
For example, a textview, we want to draw him a few layers of background, such as to draw him a 2-story background, and then the top is the text. Native TextView uses the OnDraw method to draw the text to be displayed, which is called Super.ondraw ();
So we need to rewrite the OnDraw after extends TextView, and then we can draw 2 rectangles here, and finally call Super.ondraw to display the text.
Public classMytextviewextendsTextView {PrivatePaint mPaint1, MPaint2; PublicMytextview (Context context) {Super(context); Initview (); } PublicMytextview (Context context, AttributeSet attrs) {Super(context, attrs); Initview (); } PublicMytextview (Context context, AttributeSet attrs,intdefstyleattr) { Super(context, attrs, defstyleattr); Initview (); } Private voidInitview () {mPaint1=NewPaint (); Mpaint1.setcolor (Getresources (). GetColor (Android. R.color.holo_blue_light)); Mpaint1.setstyle (Paint.Style.FILL); MPaint2=NewPaint (); Mpaint2.setcolor (Color.yellow); Mpaint2.setstyle (Paint.Style.FILL); } @Overrideprotected voidOnDraw (canvas canvas) {//Draw Outer RectangleCanvas.drawrect (0, 0, Getmeasuredwidth (), Getmeasuredheight (), mPaint1); //draw an inner rectangleCanvas.drawrect (25, 25, Getmeasuredwidth ()-25, Getmeasuredheight ()-25, MPaint2); Canvas.save (); Before the canvas moves, rotates, zooms, it needs to save its state first.//Pan 10 pixels before drawing textCanvas.translate (10, 0); //call the parent class to complete the method, that is, to draw the text Super. OnDraw (canvas); Canvas.restore ();//Remove the saved state, he and Canvas.save are corresponding. }}
6.2 Creating a composite control
For example, create a custom generic Topbar
... Follow up tomorrow and write again
Measurement and rendering of Android view