Custom View-a simple circular SS effect, view-circular Progress

Source: Internet
Author: User
Tags getcolor

Custom View-a simple circular SS effect, view-circular Progress

Let's take a look.

We want to implement a custom View and draw an arc-shaped custom View in another circle. The idea is as follows:

First, you must create a class ProgressView, inherit from the View class, and then override the two constructor methods. One is a parameter and the other is two parameters, because we want to use the custom control in the xml file, we must define the constructors of these two parameters. After this class is created, we will not care about it. First, we will consider the custom View we implement. We want users to specify the parts of the custom View, for example, in this Demo, we set the color and width of the outer circle, the color of the slice, and the speed of slice growth, at this time, we need to create a resource file named attrs under the res/values directory of the project directory (note that the name is random, but in most cases it is called ), then we add the desired attributes in the resource file, as shown below:

1 <? Xml version = "1.0" encoding = "UTF-8"?> 2 <resources> 3 <declare-styleable name = "ProgressView"> 4 <! -- CircleColor: Set the color of the circle border. sweepColor: Set the color of the slice transform. 5. startAngle: Set the start angle. sweepStep: Set the step size of the change. --> 6 <attr name = "circleColor" format = "color | reference"> </attr> 7 <attr name = "sweepColor" format = "color | reference"> </attr> 8 <attr name = "startAngle" format = "integer"> </attr> 9 <attr name = "sweepStep" format = "integer"> </attr> 10 <attr name = "padding" format = "integer"> </attr> 11 </declare-styleable> 12 </resources>

As you can see, the name attribute in the <declare-styleable> label is used to facilitate AttributeSet acquisition, while the name in the <attr> label, this is the property that we want the control to be able to customize, similar to the use of android: name = "" tags in xml files. The format attribute is used to set the type of parameters that can be accepted by this attribute.

After the Custom Resource class is defined, we start to write the main code in ProgressView:

1 package com. yztc. customprogressview; 2 3 import android. content. context; 4 import android. content. res. typedArray; 5 import android. graphics. canvas; 6 import android. graphics. color; 7 import android. graphics. paint; 8 import android. graphics. rectF; 9 import android. util. attributeSet; 10 import android. view. view; 11 12/** 13 * Custom 14 */15 public class ProgressView extends View {16 private int sw EepStep = 10; // The Slice step (that is, the angle) 17 private int padding = 40; // fill the gap between the outer border and the slice with 18 private int circleColor = Color. GRAY; // border Color 19 private int sweepColor = Color. BLUE; // sector color 20 private int startAngle = 90; // start angle 21 // set the Border width of the outer border circle 22 private int storke = 20; 23 24 private int sweepAngle = 0; // scanned angle 25 26 private static final int DEFAULT_WIDTH = 200; 27 private static final int DEFAULT_HEIGHT = 200; 28 29 p Ublic ProgressView (Context context) {30 super (context); 31} 32 33 // if you want to use this custom control in an xml file, then the constructor of the two parameters must be rewritten. 34 // when we use custom attributes, A AttributeSet 35 public ProgressView (Context context, AttributeSet attrs) will be passed by default) {36 super (context, attrs); 37 TypedArray array = context. obtainStyledAttributes (attrs, R. styleable. progressView); 38 if (array! = Null) {39 // get the custom attributes we set in xml 40 sweepStep = array. getInteger (R. styleable. progressView_sweepStep, sweepStep); 41 padding = array. getInteger (R. styleable. progressView_padding, padding); 42 circleColor = array. getColor (R. styleable. progressView_circleColor, circleColor); 43 sweepColor = array. getColor (R. styleable. progressView_sweepColor, sweepColor); 44 startAngle = array. getInteger (R. styleable. pr OgressView_startAngle, startAngle); 45 46 // reclaim TypeArray resource 47 array. recycle (); 48} 49} 50 51/** 52 * draw the outer border first-Internal Sector 53*54 * @ param canvas 55 */56 @ Override 57 protected void onDraw (Canvas canvas) {58 Paint mPaint = new Paint (); 59 mPaint. setAntiAlias (true); // set the anti-sawtooth 60 // draw the outer circle 61 mPaint. setColor (circleColor); 62 mPaint. setStrokeWidth (storke); 63 mPaint. setStyle (Paint. style. STROKE); // set the circle to hollow Circle 64 // here we get the Height and Width of the control, and determine the position of the center of the circle Based on Heigh and Width to draw the outer circle 65 canvas. drawCircle (getWidth ()/2, getWidth ()/2, getWidth ()/2-storke/2, mPaint); 66 // Log. d ("tag", "onDraw:" + getWidth (); 67 invalidate (); // request to redraw view 68 69 // draw the internal Sector 70 mPaint. setStyle (Paint. style. FILL_AND_STROKE); 71 mPaint. setColor (sweepColor); 72/* 73 drawArc (RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint) 74 RectF oval specifies the slice rectangular container object specifies the ARC's outer contour of the rectangle 75 float startAngle indicates the ARC's starting angle 76 float sweepAngle indicates the arc has swept through angle clockwise direction 77 boolean useCenter if set true: the center of the arc is included when the arc is drawn, it refers to draw an arc (slice) with a fixed center of the circle. 78 if it is set to false, the slice will be drawn irregularly 79 Paint paint brush color fill 80 81 public RectF (float left, float top, float right, float bottom) 82 x coordinate of the left point (left cut point) of the float left rectangle 83 float top rectangular top point (top cut point) Y axis coordinate 84 float right, x coordinate 85 floa of the right vertex (right slit) of the rectangle T The y coordinate of the bottom point (bottom cut point) of the bottom rectangle 86 */87 // four parameters in RectF, coordinates 88 RectF rectF = new RectF (padding + storke, padding + storke, getWidth ()-padding-storke, getWidth () -padding-storke); 89 canvas. drawArc (rectF, startAngle, sweepAngle, true, mPaint); 90 91 sweepAngle + = sweepStep; // update the scanned angle according to the step. 92 sweepAngle = sweepAngle> 360? 0: sweepAngle; 93 invalidate (); // re-paint view 94} 95 96 // onMeasure () because the inherited View is a custom View () method to Override 97 @ Override 98 protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {99 int wMode = MeasureSpec. getMode (widthMeasureSpec); 100 int hMode = MeasureSpec. getMode (heightMeasureSpec); 101 int wSize = MeasureSpec. getSize (widthMeasureSpec); 102 int hSize = MeasureSpec. getSize (heightMeasureSpec ); 103 104 // because the circle is drawn, you can judge one of the height or width. 105 switch (wMode) {106 case MeasureSpec. AT_MOST: // android: layout_width = "warp_content" 107 // obtain the screen pixel 108 float density = getResources (). getDisplayMetrics (). density; 109 wSize = (int) (DEFAULT_WIDTH * density); 110 hSize = (int) (DEFAULT_HEIGHT * density); 111 break; 112 // when the width and height of the control specified in xml are match_parent or the width of the specified value is high, the following code is called back: 113 case MeasureSpec. EXACTLY: // android: layout_width = "match_parent" android: layout_width = "40dp" 114 wSize = hSize = Math. min (wSize, hSize); 115 break; 116} 117 // As Long As You override the onMeasure () method, you must call the following method. Otherwise, the error 118 setMeasuredDimension (wSize, hSize) will be reported ); 119} 120}

First draw an external circle, that is, use the drawCircle () method. Here we call getWidth () and getHeight () to get the size of the control set in the layout, because it is a circle, therefore, getWidth ()/2 can be used to represent the center position. When an internal arc is drawn, the center of the circle is determined. The coordinates of the Left vertex are the border of the outer circle plus the distance between the arc and the original padding, the x coordinate of the right vertex is getWidth () to get the total length, minus the Border width, and then minus the padding. The top margin is the same as the bottom margin. If you do not understand it, draw a picture and immediately understand it. Comments are provided in most areas that are hard to understand ~

Then we introduce our custom View in the layout:

 1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout 3     xmlns:android="http://schemas.android.com/apk/res/android" 4     xmlns:tools="http://schemas.android.com/tools" 5     xmlns:app="http://schemas.android.com/apk/res-auto" 6     android:layout_width="match_parent" 7     android:layout_height="match_parent" 8     android:paddingBottom="@dimen/activity_vertical_margin" 9     android:paddingLeft="@dimen/activity_horizontal_margin"10     android:paddingRight="@dimen/activity_horizontal_margin"11     android:paddingTop="@dimen/activity_vertical_margin"12     tools:context="com.yztc.customprogressview.MainActivity">13 14     <com.yztc.customprogressview.ProgressView15         android:id="@+id/pv"16         android:layout_width="match_parent"17         android:layout_height="match_parent"18         android:background="#0000ff"19         app:padding="20"20         app:circleColor="#aa0000"21         app:sweepColor="#00aa00"22         app:sweepStep="1"23         app:startAngle="180"24         />25 </RelativeLayout>

It should be noted that we need to add this piece of code under the layout and Tag: xmlns: app = "http://schemas.android.com/apk/res-auto"

This parameter is used to specify the attributes that we can use in attrs ~, In the form of app: attributes you define. Of course, this app is not a fixed method, as long as it is consistent with the field after the xmlns code you added above ~

 

 

Note that:

By default, when you use the drawCircle () method of the Canvas class to draw a circle, the radius of the circle is the radius you specify and the length of the half side is added. For example, if your border size is 10, radius = 50, then the radius of the actual hollow part is 55. note this. Otherwise, the four Split points of the drawn circle may be different from those of other positions, similar to the effect of sawtooth. For details, see the Rect border problem of drawCircle.

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.