├── demo.png
├── res
├── drawable-hdpi
│ └── ic_launcher.png
├── drawable-ldpi
│ └── ic_launcher.png
├── drawable-mdpi
│ └── ic_launcher.png
├── drawable-xhdpi
│ └── ic_launcher.png
├── values
│ └── strings.xml
└── layout
│ └── main.xml
├── README.md
├── local.properties
├── project.properties
├── ant.properties
├── AndroidManifest.xml
├── proguard-project.txt
└── src
└── com
└── qiuqiaohua
├── CircleProgress
└── MyActivity.java
└── widget
└── CircleProgress.java
/demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/487qq/CircleProgress/HEAD/demo.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/487qq/CircleProgress/HEAD/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/487qq/CircleProgress/HEAD/res/drawable-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/487qq/CircleProgress/HEAD/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/487qq/CircleProgress/HEAD/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | CircleProgress
2 | ==============
3 |
4 | an Android CircleProgress;
5 | Has 3 style;
6 | 圆形,扇形,圆弧
7 | 
8 |
9 |
--------------------------------------------------------------------------------
/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | CircleProgress
4 |
5 |
--------------------------------------------------------------------------------
/local.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must *NOT* be checked into Version Control Systems,
5 | # as it contains information specific to your local configuration.
6 |
7 | # location of the SDK. This is only used by Ant
8 | # For customization when using a Version Control System, please read the
9 | # header note.
10 | sdk.dir=/home/qiuqiaohua/Applications/android-sdk-linux
11 |
--------------------------------------------------------------------------------
/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-10
15 |
--------------------------------------------------------------------------------
/ant.properties:
--------------------------------------------------------------------------------
1 | # This file is used to override default values used by the Ant build system.
2 | #
3 | # This file must be checked into Version Control Systems, as it is
4 | # integral to the build system of your project.
5 |
6 | # This file is only used by the Ant script.
7 |
8 | # You can use this to override default values such as
9 | # 'source.dir' for the location of your java source folder and
10 | # 'out.dir' for the location of your output folder.
11 |
12 | # You can also use it define how the release builds are signed by declaring
13 | # the following properties:
14 | # 'key.store' for the location of your keystore and
15 | # 'key.alias' for the name of the key to use.
16 | # The password will be asked during the build when you use the 'release' target.
17 |
18 |
--------------------------------------------------------------------------------
/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/res/layout/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
12 |
15 |
18 |
19 |
22 |
25 |
26 |
27 |
30 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/src/com/qiuqiaohua/CircleProgress/MyActivity.java:
--------------------------------------------------------------------------------
1 | package com.qiuqiaohua.CircleProgress;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Color;
5 | import android.os.AsyncTask;
6 | import android.os.Bundle;
7 | import android.view.View;
8 | import android.widget.Button;
9 | import com.qiuqiaohua.widget.CircleProgress;
10 |
11 | public class MyActivity extends Activity {
12 | /**
13 | * Called when the activity is first created.
14 | */
15 | CircleProgress arc;
16 | CircleProgress sector;
17 | CircleProgress round;
18 | Button arcBtn;
19 | Button sectorBtn;
20 | Button roundBtn;
21 |
22 |
23 |
24 | @Override
25 | public void onCreate(Bundle savedInstanceState) {
26 | super.onCreate(savedInstanceState);
27 | setContentView(R.layout.main);
28 |
29 | arc= (CircleProgress) findViewById(R.id.arc);
30 | sector= (CircleProgress) findViewById(R.id.sector);
31 | round= (CircleProgress) findViewById(R.id.round);
32 |
33 |
34 | arcBtn= (Button) findViewById(R.id.artBtn);
35 | sectorBtn= (Button) findViewById(R.id.sectorBtn);
36 | roundBtn= (Button) findViewById(R.id.rounBtn);
37 | arcBtn.setOnClickListener(onClickListener);
38 | sectorBtn.setOnClickListener(onClickListener);
39 | roundBtn.setOnClickListener(onClickListener);
40 |
41 | }
42 |
43 |
44 | private View.OnClickListener onClickListener=new View.OnClickListener() {
45 | @Override
46 | public void onClick(View v) {
47 | switch (v.getId()){
48 |
49 | case R.id.artBtn:
50 | arc.setType(CircleProgress.ARC);
51 | new AsyncTask() {
52 | @Override
53 | protected Integer doInBackground(Integer... params) {
54 | for(int i=0;i<=100;i++){
55 | publishProgress(i);
56 | try {
57 | Thread.sleep(500);
58 | } catch (InterruptedException e) {
59 | e.printStackTrace();
60 | }
61 | }
62 | return null;
63 | }
64 |
65 | @Override
66 | protected void onProgressUpdate(Integer... values) {
67 | super.onProgressUpdate(values);
68 | arc.setmSubCurProgress(values[0]);
69 | }
70 | }.execute(0);
71 | break;
72 | case R.id.sectorBtn:
73 | sector.setType(CircleProgress.SECTOR);
74 |
75 | new AsyncTask() {
76 | @Override
77 | protected Integer doInBackground(Integer... params) {
78 | for(int i=0;i<=100;i++){
79 | publishProgress(i);
80 | try {
81 | Thread.sleep(500);
82 | } catch (InterruptedException e) {
83 | e.printStackTrace();
84 | }
85 | }
86 | return null;
87 | }
88 |
89 | @Override
90 | protected void onProgressUpdate(Integer... values) {
91 | super.onProgressUpdate(values);
92 | sector.setmSubCurProgress(values[0]);
93 | }
94 |
95 |
96 | }.execute(0);
97 | break;
98 | case R.id.rounBtn:
99 | round.setType(CircleProgress.ROUND);
100 |
101 | new AsyncTask() {
102 | @Override
103 | protected Integer doInBackground(Integer... params) {
104 | for(int i=0;i<=100;i++){
105 | publishProgress(i);
106 | try {
107 | Thread.sleep(500);
108 | } catch (InterruptedException e) {
109 | e.printStackTrace();
110 | }
111 | }
112 | return null;
113 | }
114 |
115 | @Override
116 | protected void onProgressUpdate(Integer... values) {
117 | super.onProgressUpdate(values);
118 | round.setmSubCurProgress(values[0]);
119 | }
120 | }.execute(0);
121 | break;
122 | }
123 | }
124 | };
125 | }
126 |
--------------------------------------------------------------------------------
/src/com/qiuqiaohua/widget/CircleProgress.java:
--------------------------------------------------------------------------------
1 | package com.qiuqiaohua.widget;
2 |
3 | import android.content.Context;
4 | import android.graphics.*;
5 | import android.util.AttributeSet;
6 | import android.view.View;
7 |
8 | public class CircleProgress extends View
9 | {
10 | private CircleAttribute mCircleAttribute;
11 | private int mMaxProgress = 100;
12 | private int mSubCurProgress;
13 |
14 | public static final int ARC=0;
15 | public static final int SECTOR=1;
16 | public static final int ROUND=2;
17 |
18 | private int type=ARC;
19 |
20 | public CircleProgress(Context paramContext)
21 | {
22 | this(paramContext,null);
23 | }
24 |
25 | public CircleProgress(Context paramContext, AttributeSet paramAttributeSet)
26 | {
27 | super(paramContext, paramAttributeSet);
28 | defaultParam();
29 | }
30 |
31 | private void defaultParam()
32 | {
33 | this.mCircleAttribute = new CircleAttribute();
34 | this.mMaxProgress = 100;
35 | this.mSubCurProgress = 0;
36 | }
37 |
38 | public void onDraw(Canvas canvas)
39 | {
40 | super.onDraw(canvas);
41 | float f1 = 360.0F * this.mSubCurProgress / this.mMaxProgress;
42 | Rect textBounds = new Rect();
43 | String str = String.valueOf(this.mSubCurProgress + "%");
44 | this.mCircleAttribute.mTextPaint.getTextBounds(str, 0, str.length(), textBounds);//get text bounds, that can get the text width and height
45 | int textHeight = textBounds.bottom - textBounds.top;
46 |
47 | switch (type){
48 | case ARC:
49 | canvas.drawArc(this.mCircleAttribute.mRoundOval, 0.0F, 360.0F, this.mCircleAttribute.mBRoundPaintsFill, this.mCircleAttribute.mBottomPaint);
50 | canvas.drawArc(this.mCircleAttribute.mRoundOval, this.mCircleAttribute.mDrawPos, f1, this.mCircleAttribute.mBRoundPaintsFill, this.mCircleAttribute.mSubPaint);
51 | canvas.drawArc(this.mCircleAttribute.inRoundOval, 0.0F, 360.0F, this.mCircleAttribute.mBRoundPaintsFill, this.mCircleAttribute.mMainPaints);
52 | canvas.drawText(this.mSubCurProgress + "%", this.mCircleAttribute.mRoundOval.centerX(), this.mCircleAttribute.mRoundOval.centerY()+textHeight/2,this.mCircleAttribute.mTextPaint);
53 | break;
54 | case SECTOR:
55 | this.mCircleAttribute.mTextPaint.setColor(Color.WHITE);
56 | canvas.drawArc(this.mCircleAttribute.mRoundOval, 0.0F, 360.0F, this.mCircleAttribute.mBRoundPaintsFill, this.mCircleAttribute.mBottomPaint);
57 | canvas.drawArc(this.mCircleAttribute.mRoundOval, this.mCircleAttribute.mDrawPos, f1, this.mCircleAttribute.mBRoundPaintsFill, this.mCircleAttribute.mSubPaint);
58 | canvas.drawText(this.mSubCurProgress + "%", this.mCircleAttribute.mRoundOval.centerX(), this.mCircleAttribute.mRoundOval.centerY()+textHeight/2,this.mCircleAttribute.mTextPaint);
59 | break;
60 | case ROUND:
61 | float top=this.mCircleAttribute.mRoundOval.height()-this.mCircleAttribute.mRoundOval.height()*this.mSubCurProgress/100;
62 | this.mCircleAttribute.mTextPaint.setColor(Color.WHITE);
63 | canvas.drawArc(this.mCircleAttribute.mRoundOval, 0.0F, 360.0F, this.mCircleAttribute.mBRoundPaintsFill, this.mCircleAttribute.mBottomPaint);
64 |
65 | canvas.save();
66 | RectF rectF=new RectF();
67 | rectF.set(this.mCircleAttribute.mRoundOval.left,top,this.mCircleAttribute.mRoundOval.right,this.mCircleAttribute.mRoundOval.bottom);
68 | canvas.clipRect(rectF);
69 | canvas.drawArc(this.mCircleAttribute.mRoundOval, 0.0F, 360.0F, true, this.mCircleAttribute.mSubPaint);
70 | canvas.restore();
71 | canvas.drawText(this.mSubCurProgress + "%", this.mCircleAttribute.mRoundOval.centerX(), this.mCircleAttribute.mRoundOval.centerY()+textHeight/2,this.mCircleAttribute.mTextPaint);
72 | break;
73 | }
74 |
75 | }
76 |
77 | /**
78 | * 设置进度
79 | * @param progress 取值范围0-100
80 | */
81 | public void setmSubCurProgress(int progress){
82 | this.mSubCurProgress=progress;
83 | invalidate();
84 | }
85 |
86 | /**
87 | * 设置圆形进度条的样式
88 | * @param type ARC,SECTOR,ROUND
89 | */
90 | public void setType(int type) {
91 | this.type = type;
92 | }
93 |
94 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
95 | {
96 | int i = View.MeasureSpec.getSize(widthMeasureSpec);
97 | View.MeasureSpec.getSize(heightMeasureSpec);
98 | setMeasuredDimension(resolveSize(i, widthMeasureSpec), resolveSize(i, heightMeasureSpec));
99 | }
100 |
101 | protected void onSizeChanged(int paramInt1, int paramInt2, int paramInt3, int paramInt4)
102 | {
103 | super.onSizeChanged(paramInt1, paramInt2, paramInt3, paramInt4);
104 | this.mCircleAttribute.autoFix(paramInt1, paramInt2);
105 | }
106 |
107 |
108 | class CircleAttribute
109 | {
110 | public boolean mBRoundPaintsFill = true;
111 | public Paint mBottomPaint;
112 | public int mDrawPos = -90;
113 | public Paint mMainPaints ;
114 | public int mSubPaintColor = Color.parseColor("#13DEFF");
115 | public int mBottomPaintColor=Color.parseColor("#898989");
116 | public int mMainPaintColor=Color.WHITE;
117 | public int mPaintWidth = 0;
118 | public RectF mRoundOval = new RectF();
119 | public RectF inRoundOval = new RectF();
120 | public int mSidePaintInterval = 8;
121 | public Paint mSubPaint;
122 | public Paint mTextPaint;
123 | public int mTextPaintColor=Color.parseColor("#898989");
124 | public int mTextSize=22;
125 |
126 | public CircleAttribute()
127 | {
128 | this.mMainPaints=new Paint();
129 | this.mMainPaints.setAntiAlias(true);
130 | this.mMainPaints.setStyle(Paint.Style.FILL);
131 | this.mMainPaints.setStrokeWidth(this.mPaintWidth);
132 | this.mMainPaints.setColor(this.mMainPaintColor);
133 | this.mSubPaint = new Paint();
134 | this.mSubPaint.setAntiAlias(true);
135 | this.mSubPaint.setStyle(Paint.Style.FILL);
136 | this.mSubPaint.setStrokeWidth(this.mPaintWidth);
137 | this.mSubPaint.setColor(this.mSubPaintColor);
138 | this.mBottomPaint = new Paint();
139 | this.mBottomPaint.setAntiAlias(true);
140 | this.mBottomPaint.setStyle(Paint.Style.FILL);
141 | this.mBottomPaint.setStrokeWidth(this.mPaintWidth);
142 | this.mBottomPaint.setColor(this.mBottomPaintColor);
143 | this.mTextPaint=new Paint();
144 | this.mTextPaint.setAntiAlias(true);
145 | this.mTextPaint.setColor(this.mTextPaintColor);
146 | this.mTextPaint.setTextSize(this.mTextSize);
147 | this.mTextPaint.setTextAlign(Paint.Align.CENTER);
148 | }
149 |
150 | public void autoFix(int width, int height)
151 | {
152 | this.inRoundOval.set(this.mPaintWidth / 2 + this.mSidePaintInterval, this.mPaintWidth / 2 + this.mSidePaintInterval, width - this.mPaintWidth / 2 - this.mSidePaintInterval, height - this.mPaintWidth / 2 - this.mSidePaintInterval);
153 | int left = CircleProgress.this.getPaddingLeft();
154 | int right = CircleProgress.this.getPaddingRight();
155 | int top = CircleProgress.this.getPaddingTop();
156 | int bottom = CircleProgress.this.getPaddingBottom();
157 | this.mRoundOval.set(left + this.mPaintWidth / 2, top + this.mPaintWidth / 2, width - right - this.mPaintWidth / 2, height - bottom - this.mPaintWidth / 2);
158 | }
159 |
160 | // public void setPaintColor(int paintColor)
161 | // {
162 | // this.mMainPaints.setColor(paintColor);
163 | // int i = 0x66000000 | 0xFFFFFF & paintColor;
164 | // this.mSubPaint.setColor(i);
165 | // }
166 | //
167 | // public void setPaintWidth(int paintWidth)
168 | // {
169 | // this.mMainPaints.setStrokeWidth(paintWidth);
170 | // this.mSubPaint.setStrokeWidth(paintWidth);
171 | // this.mBottomPaint.setStrokeWidth(paintWidth);
172 | // }
173 | }
174 | }
--------------------------------------------------------------------------------