Objective
Android custom controls often use canvas to draw 2D graphics and must be proficient in canvas drawing mechanisms before optimizing their own custom control skills. This paper explains the canvas drawing mechanism from the following three aspects:
Canvas Canvas
Brush Paint
Sample Circular progress bar
Canvas Canvas
First, take a look at the Android website definition of the canvas class:
The Canvas class holds the "draw" calls. To draw something, your need 4 basic components:a Bitmap to hold the pixels, A Canvas to host the draw calls (writing into The bitmap), a drawing primitive (eg, Rect, Path, Text, bitmap), and a paint (to describe the colors and styles for the draw ing).
Simply put, the Android 2D drawing must have the support of the Canvas class, which is located under the "Android.graphics.Canvas" package. We can interpret canvas as a piece of memory that the system assigns to US (PS: The real memory is the bitmap it contains).
The canvas provides two constructors:
Canvas (): Creates an empty Canvas object.
Canvas (Bitmap Bitmap): Creates a Canvas with a Bitmap bitmap background.
In general, we will use the second constructor method that contains the bitmap parameter or the canvas provided by the system directly in the OnDraw method.
Since canvas is primarily used for drawing, it provides a number of corresponding draw methods that allow us to draw on canvas objects and introduce several common draw methods:
void DrawRect (RECTF rect, Paint Paint): area where the area is drawn, and the parameter is RECTF.
void DrawOval (RECTF oval, Paint Paint): Draws a rectangle's inner-cut ellipse.
void Drawcircle (float cx, float CY, float radius, Paint Paint): Draws a circle. CX and CY are center coordinates and radius is the length of the radius.
void DrawArc (RECTF oval, float startangle, float sweepangle. Boolean usecenter, Paint Paint): Draws a circular arc, but also takes the inner-cut ellipse of the rectangle as the standard. Where the startangle is the starting angle, the sweepangle is radians, and Usecenter is true, a fan row is drawn, false, and only a circular arc. (Ps:startangle is 0 o'clock, is the circular clock 3 o'clock direction).
void DrawPath (path path, Paint Paint): Draws the line according to the given Path.
void Drawbitmap (Bitmap Bitmap, Rect src, Rect DST, Paint Paint): texture, parameter Bitmap is the Bitmap object to draw, parameter src refers to the source region of the BITMAP (typically null), DST is the target area for bitmap, paint is a brush and can be null.
void DrawLine (float startx, float starty, float stopx, float stopy, Paint Paint): Draws a line between the given starting point and end point.
void Drawpoint (float x, float y, Paint Paint): Draws a point according to the given coordinates.
void DrawText (String text, float x, float y, Paint Paint): Draws text according to the given coordinates. where x is the x-coordinate of the beginning of the text, and y is the y-coordinate of the longitudinal end of the text.
Brush Paint
From the several canvas.drawxxx () methods listed above, you can see that there is a parameter of type paint, which can be interpreted as a "brush", which is painted on the canvas of canvas. It is located under the "Android.graphics.Paint" package and is used primarily to set the drawing style, including the brush color.
Paint provides a number of ways to set the painting style, listing only some common features:
Setargb (int A, int r, int g, int b): Sets the ARGB color.
SetColor (int color): Sets the color.
Setalpha (int a): set transparency.
Setantialias (Boolean AA): Sets whether anti-aliasing.
Setshader (Shader Shader): Sets the paint fill effect.
Setstrokewidth (float width): Sets the stroke width of the paint.
SetStyle (Paint.style Style): Sets the Paint fill style.
Settextsize (float textsize): Sets the text size when drawing text.
Custom Circular Progress Bars
Here, for example, with a custom circular progress bar, let's take a look at the effect chart:
Through the effect graph, we first abstract the custom attributes, as follows:
Circle Inner Fill color.
The background color of the ring progress bar.
The color of the ring progress bar.
Ring radius.
The width of the ring progress bar.
The angle at which the progress bar starts.
The color of the middle text.
The size of the middle text.
Whether intermediate text needs to display a bit of flag.
In Android, you can create a resource source file in the res/values/directory of the project, declaring a specific set of attributes through Declare-styleable.
The sample Properties collection is shown below (Res/values/attrs_round_progress_bar.xml):
<resources>
<declare-styleable name= "Roundprogressbar" >
<attr name= "StartAngle" Integer "></attr>
<attr name=" radius "format=" Dimension "></attr>
<attr name=" Ringwidth "format=" Dimension "></attr>
<attr name=" centercolor "format=" Color "></attr>
<attr name= "ringcolor" format= "color" ></attr> <attr "name=" Progresscolor "
Color" ></attr>
<attr name= "textsize" format= "Dimension" ></attr>
<attr name= "TextColor" format= "Color" ></attr>
<attr name= "Istextdisplay" format= "boolean" ></attr>
</ Declare-styleable>
</resources>
Custom properties can be obtained by typedarray arrays in the constructor of a custom view, which we derive from the definition of a rounded view to achieve the effect of the above image (Roundprogressbar.java):
Package Love.com.progressbar.view;
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.graphics.Typeface;
Import Android.util.AttributeSet;
Import Android.util.TypedValue;
Import Android.view.View;
Import LOVE.COM.PROGRESSBAR.R;
public class Roundprogressbar extends View {private static final int start_angle =-90;
private static final String Center_color = "#eeff06";
private static final String Ring_color = "#FF7281E1";
private static final String Progress_color = "#FFDA0F0F";
private static final String Text_color = "#FF000000";
private static final int text_size = 30;
private static final int circle_radius = 20;
private static final int ring_width = 5;
/** * The starting angle of the arc, reference Canvas.drawarc method * * Private int startangle;
/** * Circular inner radius/private int radius; /** * The width of the progress bar * * * Private int Ringwidth;
/** * Default progress/private int mprogress = 0;
/** * Round Inner Fill Color * * private int centercolor;
/** * progress bar background color * * private int ringcolor;
/** * The color of the progress bar * * private int progresscolor;
/** * Text Size * * private int textsize;
/** * Text color * * private int textcolor;
/** * Text is required to display * * Private Boolean Istextdisplay;
Private String textcontent;
Private Paint Mpaint;
Public Roundprogressbar {This (context, NULL);
Public Roundprogressbar (context, AttributeSet attrs) {This (context, attrs, 0);
Public Roundprogressbar (context, AttributeSet attrs, int defstyle) {Super (context, attrs, Defstyle);
Gets the custom attribute TypedArray a = context.obtainstyledattributes (Attrs, R.styleable.roundprogressbar);
for (int i = 0; i < a.length (); i + +) {int attr = A.getindex (i); Switch (attr) {case R.styleable.roundprogressbar_startangle:startangLe = A.getinteger (attr, Start_angle);
Break
Case R.styleable.roundprogressbar_centercolor:centercolor = A.getcolor (attr, Color.parsecolor (CENTER_COLOR));
Break Case R.styleable.roundprogressbar_progresscolor:progresscolor = A.getcolor (attr, Color.parsecolor (PROGRESS_COLO
R));
Break
Case R.styleable.roundprogressbar_ringcolor:ringcolor = A.getcolor (attr, Color.parsecolor (Ring_color));
Break
Case R.styleable.roundprogressbar_textcolor:textcolor = A.getcolor (attr, Color.parsecolor (Text_color));
Break
Case r.styleable.roundprogressbar_textsize:textsize = (int) a.getdimension (attr, Typedvalue.applydimension (
TYPEDVALUE.COMPLEX_UNIT_SP, Text_size, Getresources (). Getdisplaymetrics ());
Break
Case r.styleable.roundprogressbar_istextdisplay:istextdisplay = A.getboolean (attr, true); Break
Case R.styleable.roundprogressbar_radius:radius = (int) a.getdimension (attr, Typedvalue.applydimension (
Typedvalue.complex_unit_dip, Circle_radius, Getresources (). Getdisplaymetrics ());
Break
Case r.styleable.roundprogressbar_ringwidth:ringwidth = (int) a.getdimension (attr, Typedvalue.applydimension (
Typedvalue.complex_unit_dip, Ring_width, Getresources (). Getdisplaymetrics ());
Break
Default:break;
} a.recycle ();
Initializes the Brush setting setpaint ();
private void Setpaint () {mpaint = new Paint ();
Mpaint.setantialias (TRUE);
} @Override protected void OnDraw (Canvas Canvas) {Super.ondraw (Canvas);
Get center coordinates int cx = getwidth ()/2;
int cy = CX;
/** * Draw Center Color */if (centercolor!= 0) {drawcentercircle (canvas, CX, CY);
/** * Painting Outer Circle * * Drawoutercircle (Canvas, CX, CY);
/** * Draw Progress Arc * * * drawprogress (canvas, CX, CY);
/** * Draw a percentage of progress * * * Drawprogresstext (canvas, CX, CY);
private void Drawprogresstext (Canvas Canvas, int cx, int cy) {if (!istextdisplay) {return;
} mpaint.setcolor (TextColor);
Mpaint.settextsize (TEXTSIZE);
Mpaint.settypeface (Typeface.default_bold);
Mpaint.setstrokewidth (0);
Textcontent = getprogress () + "%";
float textWidth = Mpaint.measuretext (textcontent);
Canvas.drawtext (Textcontent, CX-TEXTWIDTH/2, Cy + TEXTSIZE/2, mpaint);
private void Drawprogress (Canvas Canvas, int cx, int cy) {mpaint.setcolor (progresscolor);
Mpaint.setstrokewidth (Ringwidth);
Mpaint.setstyle (Paint.Style.STROKE);
RECTF MRECTF = new RECTF (Cx-radius, Cy-radius, cx + radius, cy + radius);
float sweepangle = (float) (mprogress * 360.0/100);
Canvas.drawarc (MRECTF, StartAngle, Sweepangle, False, Mpaint);
}private void Drawoutercircle (Canvas Canvas, int cx, int cy) {mpaint.setstyle (Paint.Style.STROKE);
Mpaint.setcolor (Ringcolor);
Mpaint.setstrokewidth (Ringwidth);
Canvas.drawcircle (CX, CY, RADIUS, mpaint);
private void Drawcentercircle (Canvas Canvas, int cx, int cy) {mpaint.setcolor (centercolor);
Mpaint.setstyle (Paint.Style.FILL);
Canvas.drawcircle (CX, CY, RADIUS, mpaint);
public synchronized int getprogress () {return mprogress;
Public synchronized void setprogress (int progress) {if (Progress < 0) {progress = 0;
else if (Progress > MB) {progress = 100;
} mprogress = progress;
When the progress is changed, it is necessary to redraw the postinvalidate () by Invalidate method;
}
}
In a Mainactivity.java layout file, you can call a circular progress bar like this:
<?xml version= "1.0" encoding= "Utf-8"?> <relativelayout xmlns:android=
"http://schemas.android.com/apk" /res/android "
xmlns:round=" Http://schemas.android.com/apk/res-auto "
android:layout_width=" match_parent "
android:layout_height=" match_parent ">
<love.com.progressbar.view.roundprogressbar
android: Id= "@+id/id_round_progressbar"
android:layout_width= "400DP"
android:layout_height= "400DP"
round: radius= "100DP"
round:ringwidth= "20DP"
round:startangle= " -90"
round:centercolor= "#eeff06"
Round:ringcolor= "#e16556e6"
round:progresscolor= "#d20c0c"
round:textcolor= "#000000"
round: Textsize= "20SP"
round:istextdisplay= "true"/>
</RelativeLayout>
wherexmlns:round= "Http://schemas.android.com/apk/res-auto" is the namespace of the added import Custom View property in Android Studio.
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.