Android Custom view to achieve a simple circular progress effect _android

Source: Internet
Author: User
Tags border color getcolor tag name

First show you the effect of the picture, if it feels good, please refer to the realization of ideas:

We're going to implement a custom view of another circle that draws an arc, and the idea is this:

First you create a class Progressview, inherit from the view class, and then rewrite two of them, one argument and two arguments, because we want to use the custom control in an XML file, so we have to define the constructor for this two parameter. Once we've created this class, we're not going to take care of it. Consider the custom view that we implemented first, and what we want to make of it can be specified by the user himself, such as the outer frame color and width of the outer circle of the demo, and the color of the fan part, the speed of the fan growth, etc. At this time we want to create a resource file in the Res/values directory of the Project engineering directory named ATTRS (note that the name is random, just in most cases), and then we add the attributes we want to the resource file as follows:

<?xml version= "1.0" encoding= "Utf-8"?>
<resources>
<declare-styleable name= "Progressview" >
<!--circlecolor Set the color of the round border Sweepcolor set the color of the pie transform
startangle Set the starting angle Sweepstep set the step of the transform-->
< attr name= "Circlecolor" format= "color|reference" ></attr>
<attr name= "Sweepcolor" format= "color|" Reference "></attr>
<attr name=" startangle "format=" integer "></attr>
<attr name=" Sweepstep "format=" "integer" ></attr>
<attr name= "padding" format= "integer" ></attr>
</declare-styleable>
</resources>

You can see that the Name property in the,<declare-styleable> tab is used to facilitate our acquisition of AttributeSet, and the <attr> tag name is the part of the property that we want the control to customize. Similar to the use of tags such as android:name= "" in an XML file. The Format property is the type of parameter that the property is set to accept.

Defining the custom resource class, we started writing the main code in Progressview:

Package Com.yztc.customprogressview;
Import Android.content.Context;
Import Android.content.res.TypedArray;
Import Android.graphics.Canvas;
Import Android.graphics.Color;
Import Android.graphics.Paint;
Import Android.graphics.RectF;
Import Android.util.AttributeSet;
Import Android.view.View; /** * Custom/public class Progressview extends view {private int sweepstep = 10;//Sector Transform's step (that is, angle) private int padding = 40 //Outer box distance fan-shaped distance fills private int circlecolor = color.gray;//border color private int sweepcolor = color.blue;//sector color private int Start
Angle = 90;//Starting angle//set border thickness of outer frame round private int storke = 20;
private int sweepangle = 0;//swept angle private static final int default_width = 200;
private static final int default_height = 200; Public Progressview {Super (context);}//If you want to use the custom control in an XML file, you must override the constructor of two parameters//Because when we use custom attributes,
Will default to pass over a attributeset set public progressview (context, AttributeSet attrs) {Super (context, attrs); TypedArray array = context.obtainstyledattributes (Attrs, R.STyleable.
Progressview);
if (array!= null) {//Get each custom attribute we set in the XML sweepstep = Array.getinteger (R.styleable.progressview_sweepstep, sweepstep);
padding = Array.getinteger (r.styleable.progressview_padding, padding);
Circlecolor = Array.getcolor (R.styleable.progressview_circlecolor, Circlecolor);
Sweepcolor = Array.getcolor (R.styleable.progressview_sweepcolor, Sweepcolor);
StartAngle = Array.getinteger (R.styleable.progressview_startangle, startangle);
Recycling Typearray Resources array.recycle ();
}/** * First draw the outer frame--Inner sector * * @param canvas/@Override protected void OnDraw (canvas canvas) {Paint mpaint = new Paint (); Mpaint.setantialias (TRUE);
Set anti-aliasing//Draw outer Circle box Mpaint.setcolor (Circlecolor);
Mpaint.setstrokewidth (Storke);
Mpaint.setstyle (Paint.Style.STROKE)//set round to hollow circle//Here we get the height and width of the control, determine the position of the center of the circle according to Heigh and width to draw the outer circle
Canvas.drawcircle (GetWidth ()/2, getwidth ()/2, getwidth ()/2-STORKE/2, mpaint);
LOG.D ("tag", "OnDraw:" +getwidth ()); Invalidate ()//Request redraw view//Draw the inner fan Mpaint.setstyle (PainT.style.fill_and_stroke);
Mpaint.setcolor (Sweepcolor); /* DRAWARC (RECTF oval, float startangle, float sweepangle, boolean usecenter,paint Paint) RECTF Oval Specifies that the rectangular container object of the specified sector specifies the outer contour of the arc. The rectangular float startangle represents the starting angle of the arc. The float sweepangle indicates that the arc passes through the angle of the sweep clockwise in a Boolean usecenter if set to true to include the center of a circle when drawing an arc, it means to draw an arc with a fixed center of the circle Shape (PIE), if specified as false, the irregularly drawn pie Paint Paint Brush Color fills public rectf (float left, float top, float right, float bottom) float left The x coordinate of the left point of the rectangle (the left tangent) is the y-coordinate of the top (tangent) of the upper rectangle float right, the x-coordinate of the right point (right tangent) of the rectangle (bottom) of the y-coordinate of the bottom point (tangent) of the rectangle (tangency), respectively, corresponds to the four parameters of the//RECTF. The coordinates of its incircle four tangent points RECTF RECTF = new RECTF (padding + storke, padding + Storke, getwidth ()-Padding-storke, GetWidth ()-Paddi
Ng-storke);
Canvas.drawarc (RECTF, StartAngle, Sweepangle, True, Mpaint); Sweepangle + = sweepstep;//based on step update swept angle Sweepangle = sweepangle > 360?
0:sweepangle; Invalidate (),//redrawing view}//Because we are inherited view from the defined view, the Onmeasure () method overrides @Override protected void onmeasure (int Widthmeasurespec, int heightmeasurespec) {int wmode = Measurespec.GetMode (WIDTHMEASURESPEC);
int hmode = Measurespec.getmode (Heightmeasurespec);
int wsize = measurespec.getsize (Widthmeasurespec);
int hsize = measurespec.getsize (Heightmeasurespec);
Because a circle is drawn, it is OK to judge one of the heights or widths. Switch (wmode) {case measurespec.at_most://android:layout_width= "warp_content"//get screen pixel float density = getresources ()
. Getdisplaymetrics (). density;
wsize = (int) (default_width * density);
hsize = (int) (default_height * density);
Break Callback the following code case measurespec.exactly://android:layout_width= "Match_parent" when the width of the specified control in the XML is match_parent or when the specified value is wide-high.
Android:layout_width= "40DP" wsize = Hsize = Math.min (wsize, hsize);
Break
//As long as you rewrite the Onmeasure () method, be sure to call the following methods, or you will error setmeasureddimension (wsize, hsize); }
}

We first draw an outer circle, which is all using the Drawcircle () method, where we call GetWidth (), GetHeight () represents the size of the control being set in the layout, because it is a circle, so you can use GetWidth ()/second to represent the center of the circle. And when the inner arc is painted, to determine its center position, the coordinates of the left point is the outer circle of the round and arc with the original spacing padding to determine, the right point of the X coordinate is getwidth () to get the total length, minus the border width, and then subtract padding, the top and bottom margins are the same, Do not understand the drawing of a picture immediately understand. Most of the difficult to understand where there are comments, as long as the serious look will not be able to see the ~

Then we introduce our custom view in the layout:

 <?xml version= "1.0" encoding= "Utf-8"?> <relativelayout xmlns:android= "http ://schemas.android.com/apk/res/android "xmlns:tools=" Http://schemas.android.com/tools "xmlns:app=" http://
Schemas.android.com/apk/res-auto "android:layout_width=" match_parent "android:layout_height=" Match_parent "
android:paddingbottom= "@dimen/activity_vertical_margin" android:paddingleft= "@dimen/activity_horizontal_margin"
android:paddingright= "@dimen/activity_horizontal_margin" android:paddingtop= "@dimen/activity_vertical_margin"
tools:context= "Com.yztc.customprogressview.MainActivity" > <com.yztc.customprogressview.progressview Android:id= "@+id/pv" android:layout_width= "match_parent" android:layout_height= "Match_parent" android:background= "#0000ff" app:padding= "app:circlecolor=" #aa0000 "app:sweepcolor=" #00aa00 "app:sweepstep=" 1 "app:startangle=" 180 "/> </relativelayout> 

It should be noted that we need to add this code below the layout tag: xmlns:app= "Http://schemas.android.com/apk/res-auto"

Used to specify the attributes we can use to customize in our own Attrs ~, using the form of app: the attributes you define. Of course, this app is not a fixed writing, as long as you add the code above the xmlns after the field of the same is OK ~

It is also necessary to note that:

By default, the Drawcircle () method of the canvas class is used to draw a circle, and the radius of the circle is the radius you specify, plus half the length of the edge, such as your border size=10,radius=50, The actual hollow part has a radius of 55. Note This, otherwise the four tangent points of the drawn circle will be different from the other positions, similar to the appearance of jagged. See the Rect border problem with drawcircle () specifically.

The above is a small set to introduce the Android custom view to achieve a simple round progress effect, I hope to help you, if you have any questions welcome to my message, small series will promptly reply to everyone!

Related Article

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.