Android Curious baby _ watch face World _04

Source: Internet
Author: User

This one is a general idea of the ape's custom view, which explains some of the basics of custom view through a simple custom progressbar of fried chicken. Suitable for novice, master do not spray, have good guidance and ideas of welcome comments.

(1) Confirm demand

To write a custom view, first you need to determine what the requirements are. Generally includes appearance, event handling, animation effects.

Appearance requirements: The appearance of the ProgressBar is very simple, that is, two rectangles (which can also be other shapes, where we only implement the underlying rectangles) overlap display. One of the fixed size when the background, a variable width to display the scale.

Event handling: ProgressBar is not a seekbar, just a simple display scale, so there is no need to touch event handling, only one event that dynamically alters the scale to be processed.

Animation effect: No, said fried chicken simple.


(2) Confirm the parent class to inherit

By analyzing the requirements and then deciding whether to inherit existing controls or inherit the view class.

Inheriting existing controls is generally due to the fact that existing controls are broadly in line with our needs, but with a small amount of non-conformance, so we extend the existing controls. For example, a custom fillet picture control can inherit the ImageView control and then add a rounded mask layer to the draw process. In this way, we can preserve the original characteristics of ImageView and achieve our goal.

Inheriting the view class is generally because there is no suitable original control to inherit, for example we want to customize a lottery wheel.

Here our ProgressBar to inherit the view.

Do not ask why I do not inherit the system of ProgressBar, Khan ...

The ProgressBar we write here is just a learning goal, and the system's ProgressBar can be seen as a custom view implemented by Google engineers.


(3) initialization

This step is the initialization of the view, as I said in other blog posts, you can think of view and its subclasses as normal Java classes. What's special about it is that the system and the view and its subclasses have a fixed set of interactive processes, such as systems

Will call the constructor of view to create a new instance object.

Will call the measure (Int,int) method to let the view measure its size,

Call the layout () method to let the view layout the position of the sub-view relative to itself,

Call the Draw () method to have the view draw itself to a specific range on the screen.

If there is no system to do these things, then the view class is just an ordinary Java class.

(The system here actually refers to the system service Windowmanageservice, we do not drill down here)

So, first we're going to rewrite the constructor, the view class has 3 overloaded construction methods that correspond to different scenarios. This is generally similar to the following:

Public Baseprogressbar (Context context) {This (context, null);} Public Baseprogressbar (context context, AttributeSet Attrs) {This (context, attrs, 0);} Public Baseprogressbar (context context, AttributeSet attrs, int defstyleattr) {Super (context, attrs, defstyleattr); init ();}

(1) The first method of constructing a context parameter is called when the code is dynamically generated, of course, in order to keep the code logic and the view decoupled. We should construct the view in the XML file whenever possible.

(2) The second construction method is called when it is defined in the XML file, where the parameter Attrs saves the property values we have assigned in the XML file, and we need to read them out of the attrs. These properties can be either the defined properties of the view or our custom properties. When you call the Super method, super reads some common property values and saves them, such as margin, padding, and background. And then we can read our own unique property values, such as TextView textsize, TextColor, and so on. Here we do not go to custom properties, do not know can be self-check, just need to know that when we implement the color of those brushes can be used by custom attributes in the XML is assigned value.

(3) The third construction method to stay in the pit, I did not check the scene under what will be called, as if the theme style is set.


Next we initialize the other things we need to use in the init () method, we need to draw two rectangles, so we have to initialize two rectangles and draw a rectangle:

private void Init () {BACKRECTF = new RECTF (); FONTRECTF = new RECTF ();p aint1 = new Paint ();p Aint1.setantialias (true);p Aint1 . SetColor (0xfff0f0f0);p aint2 = new Paint (paint1);p Aint2.setcolor (0xffd54321);}

Someone here might wonder why the four coordinates of the two rectangles are not initialized, the background rectangle has an initial state of (0,0,view width, view height) and remains unchanged, and the foreground rectangle's initial state is (the width of the 0,0,progress/max*view, the height of the view) and changes with the progress.

It should be noted that the construction method is the first method to be called, this time the measurement, layout, etc. have not yet begun to execute, the width of the view is not calculated, so the coordinates of the rectangle initialization must be measured.

(4) Measuring logic of its own size

In fact, I used to write the measurement of their own size logic, brush what needs to add. Measuring your own size logic almost must be overridden unless you inherit an existing control, and your changes do not affect the size of the control.

As mentioned earlier, the system will call the measure (Int,int) method to allow the view to measure its size, and the measure (Int,int) method will call the Onmeasure (int,int) method to do the measurement. The function of the onmeasure (int,int) method is that different view subclasses can override this method to implement their own measurement logic. The following look at the ProgressBar onmeasure (int,int) method should be similar:

protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {int widthmode = Measurespec.getmode ( WIDTHMEASURESPEC); int widthsize = Measurespec.getsize (widthmeasurespec); int hightmode = Measurespec.getmode ( HEIGHTMEASURESPEC); int heightsize = Measurespec.getsize (heightmeasurespec); switch (widthmode) {case MeasureSpec.EXACTLY:case MeasureSpec.AT_MOST:mWidth = Widthsize;break;case MeasureSpec.UNSPECIFIED:mWidth = Getminimumwidth (); break;} Switch (hightmode) {case MeasureSpec.EXACTLY:case MeasureSpec.AT_MOST:mHeight = heightsize > getmaxheight ()? Getmaxheight (): Heightsize;break;case MeasureSpec.UNSPECIFIED:mHeight = Getminimumheight (); break;} Setmeasureddimension (Mwidth, mheight); Onmeasurecomplete ();}

The onmeasure (int,int) method has two parameters that can be interpreted as a recommendation for the size of the parent view pair view. This size is determined by the attributes of the Layout_width and Layout_height, as well as the parent view itself, set in the XML file by the child view.

Exactly: This mode when the child view is match_parent or a specific value, and size is the size of the parent.

This pattern indicates a definite size, generally we can use the recommended size of the parent directly.

At_most: This mode when the child view is wrap_content, size is the size of the parent.

We are generally dealing with this pattern, and the size of the parent is only limited as a maximum value. For example, when the width of TextView is set to wrap_content, its width should be determined by its text content and cannot exceed the width of the parent.

< Span style= "font-size:18px" > unspecified: This pattern represents uncertainty, equivalent to parent told the child view, you want to most small, I do not care. This is typically in the case of parent as a scrollable container. such as Scrollview,listview, because they can be vertical scrolling, so they do not limit the height of the view, sub-view to how high the line.

In fact, the size of the calculation is the synthesis of the parent's recommendations and view the characteristics of their own decision. For example, TextView should be based on the total width of text content, text height, number of lines and line spacing, imageview to consider the image of the original size, width and height ratio. Different controls are not the same thing to consider.

What about here? ProgressBar is relatively simple,

< Span style= "font-size:18px" > width: parent said how wide is wide. If the parent is a horizontal scrolling view, give us the suggestion that unspecified, of course, theoretically we can ask for infinitely wide, but this is obviously unreasonable, like TextView in this case, The width is just the right to display the text content. And we do not have the text content as the basis, so you can define a maximum width or minimum width or the default width, whatever you like.

< Span style= "font-size:18px" > < Span style= "font-size:18px" > height: height It is possible to set a maximum value and a minimum value to prevent the appearance of not conforming to the progressbar, such as height too small looks like a line, height is too large to look like a giant button.

< Span style= "font-size:18px" > < Span style= "font-size:18px" > to reiterate, the logic here to measure size is just my personal understanding, Everyone's ideas may not be the same. For example I think progressbar can not be too high, so I wrote the above, but you think The height of the ProgressBar can be filled with the screen, then you can go according to their own logic to achieve, as long as not too unconstrained, to consider the reality and human visual habits.


(5) Further initialization

< Span style= "font-size:18px" > < Span style= "font-size:18px" > When the measurement is complete, the view has a width and height. As a result, the initialization of the parameters that require the view's width and height can also be done:

private void Onmeasurecomplete () {backrectf.left = 0;backrectf.right = Mwidth;backrectf.top = 0;backrectf.bottom = MHeigh T;fontrectf.left = 0;fontrectf.right = mprogress * Mwidth/mmax;fontrectf.top = 0;fontrectf.bottom = MHeight;}


(6) Start painting

Here we are custom view instead of ViewGroup, so we don't have to rewrite onlayout to go to the Sub view layout, we don't have a child view at all.

< Span style= "font-size:18px" > < Span style= "font-size:18px" > Two rectangles are initialized with the brushes and coordinates, and two statements can be drawn:

protected void OnDraw (canvas canvas) {canvas.drawrect (BACKRECTF, paint1); Canvas.drawrect (FONTRECTF, paint2);}

with Similar to the onmeasure (int,int) method, the Onmeasure (Int,int) method is called when it is measured, and the OnDraw (canvas canvas) method is called when it is drawn.


(7) Event handling

ProgressBar must not always scale to 0, so provide a way to dynamically change the scale:

public void setprogress (int progress) {if (Progress > Mmax) {progress = Mmax;} if (this.mprogress = = progress) {return;} this.mprogress = Progress;fontrectf.right = mprogress * Mwidth/mmax;invalidate ();}

here are some reasonable judgments: whether to exceed the maximum value and whether it is the same as the original. Then change the right coordinate of the foreground rectangle, and finally redraw the request method: Invalidate (); The system receives invalidate (); The request will be redrawn our Progressbar,ondraw () method will be re-called, the width of the changed foreground rectangle will be drawn.

In this way, one of the most basic simple ProgressBar is done.

My focus here is on the general idea of customizing view (my idea), not to achieve a cool effect.

Of course you can do a lot of expansion on this ProgressBar basic idea.

Such as:

(1) Change to a rounded rectangle to achieve rounded corners ProgressBar. The Canvas.drawroundrect () method is to draw rounded rectangles. In the same vein, you can draw a circle or a fan.

(2) Ring ProgressBar, the basic idea is to draw a large circle, and then draw a concentric fan block part, and finally draw a small point of concentric circle. The angle of occlusion is determined by progress.

(3) Gradient ProgressBar, refers to the color gradient, the principle is very simple, add a shader to the brush on the line.

(Note: shader, I see people like this translation I said, is actually in different ways to color objects, the way is linear, round, etc. )

LinearGradient = new LinearGradient (0, 0, mwidth, Mheight, 0xffff00ff, 0X00FFFF, Shader.TileMode.MIRROR); Paint2.setshader (lineargradient);

the above setting will change the color of our progressbar linearly. Of course, the ring can also increase the color gradient, using a different shader on the line.

(4) code to write a numberprogressbar, in fact, the basic ideas are the same, just to achieve some cool effect, to do more calculations.

You can try to read it first, then try to write it yourself. I have changed it to a vertical, interested can also try it myself.

GitHub Address: Https://github.com/daimajia/NumberProgressBar


Because the source code is too simple, I will not upload. If you're unfamiliar with custom view, it's a good idea to try out some of the extensions that I've said.


I am here to focus on thinking about how to achieve the study, recommended:

http://blog.csdn.net/aigestudio/article/category/2397181

Android Curious baby _ watch face World _04

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.