在安全卫生上,经常看到有圆形的进度条在转动,效果非常好看,于是就尝试去实现一下,具体实现过程不多说了,直接上效果图,先炫耀下。
效果图:
分析:比较常见于扫描结果、进度条等场景
利用canvas.drawarc(rectf oval, float startangle, float sweepangle, boolean usecenter, paint paint)绘制圆弧
paint的一些属性定义粗细、颜色、样式等
lineargradient实现颜色的线型渐变
同样的道理,可以画出长条进度条,扇图饼图等,感兴趣可以试下..
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
package com.liujing.progressviewdemo;
/***
* 自定义圆弧进度条
*
* @author liujing
*/
public class progressview extends view {
//分段颜色
private static final int [] section_colors = { color.green, color.yellow,
color.red };
private static final string[] alarm_level = { "安全" , "低危" , "中危" , "高危" };
private float maxcount;
private float currentcount;
private int score;
private string crrentlevel;
private paint mpaint;
private paint mtextpaint;
private int mwidth, mheight;
public progressview(context context, attributeset attrs, int defstyleattr) {
super (context, attrs, defstyleattr);
init(context);
}
public progressview(context context, attributeset attrs) {
this (context, attrs, 0 );
}
public progressview(context context) {
this (context, null );
}
private void init(context context) {
mpaint = new paint();
mtextpaint = new paint();
}
@override
protected void ondraw(canvas canvas) {
super .ondraw(canvas);
initpaint();
rectf rectblackbg = new rectf( 20 , 20 , mwidth - 20 , mheight - 20 );
canvas.drawarc(rectblackbg, 0 , 360 , false , mpaint);
mpaint.setcolor(color.black);
canvas.drawtext(score + "分" , mwidth / 2 , mheight / 2 , mtextpaint);
mtextpaint.settextsize( 40 );
if (crrentlevel != null ) {
canvas.drawtext(crrentlevel, mwidth / 2 , mheight / 2 + 50 ,
mtextpaint);
}
float section = currentcount / maxcount;
if (section <= 1 .0f / 3 .0f) {
if (section != 0 .0f) {
mpaint.setcolor(section_colors[ 0 ]);
} else {
mpaint.setcolor(color.transparent);
}
} else {
int count = (section <= 1 .0f / 3 .0f * 2 ) ? 2 : 3 ;
int [] colors = new int [count];
system.arraycopy(section_colors, 0 , colors, 0 , count);
float [] positions = new float [count];
if (count == 2 ) {
positions[ 0 ] = 0 .0f;
positions[ 1 ] = 1 .0f - positions[ 0 ];
} else {
positions[ 0 ] = 0 .0f;
positions[ 1 ] = (maxcount / 3 ) / currentcount;
positions[ 2 ] = 1 .0f - positions[ 0 ] * 2 ;
}
positions[positions.length - 1 ] = 1 .0f;
lineargradient shader = new lineargradient( 3 , 3 , (mwidth - 3 )
* section, mheight - 3 , colors, null ,
shader.tilemode.mirror);
mpaint.setshader(shader);
}
canvas.drawarc(rectblackbg, 180 , section * 360 , false , mpaint);
}
private void initpaint() {
mpaint.setantialias( true );
mpaint.setstrokewidth(( float ) 40.0 );
mpaint.setstyle(style.stroke);
mpaint.setstrokecap(cap.round);
mpaint.setcolor(color.transparent);
mtextpaint.setantialias( true );
mtextpaint.setstrokewidth(( float ) 3.0 );
mtextpaint.settextalign(paint.align.center);
mtextpaint.settextsize( 50 );
mtextpaint.setcolor(color.black);
}
private int diptopx( int dip) {
float scale = getcontext().getresources().getdisplaymetrics().density;
return ( int ) (dip * scale + 0 .5f * (dip >= 0 ? 1 : - 1 ));
}
public int getscore() {
return score;
}
public string getcrrentlevel() {
return crrentlevel;
}
public void setcrrentlevel(string crrentlevel) {
this .crrentlevel = crrentlevel;
}
public float getmaxcount() {
return maxcount;
}
public float getcurrentcount() {
return currentcount;
}
public void setscore( int score) {
this .score = score;
if (score == 100 ) {
this .crrentlevel = alarm_level[ 0 ];
} else if (score >= 70 && score < 100 ) {
this .crrentlevel = alarm_level[ 1 ];
} else if (score >= 30 && score < 70 ) {
this .crrentlevel = alarm_level[ 2 ];
} else {
this .crrentlevel = alarm_level[ 3 ];
}
invalidate();
}
/***
* 设置最大的进度值
*
* @param maxcount
*/
public void setmaxcount( float maxcount) {
this .maxcount = maxcount;
}
/***
* 设置当前的进度值
*
* @param currentcount
*/
public void setcurrentcount( float currentcount) {
this .currentcount = currentcount > maxcount ? maxcount : currentcount;
invalidate();
}
@override
protected void onmeasure( int widthmeasurespec, int heightmeasurespec) {
int widthspecmode = measurespec.getmode(widthmeasurespec);
int widthspecsize = measurespec.getsize(widthmeasurespec);
int heightspecmode = measurespec.getmode(heightmeasurespec);
int heightspecsize = measurespec.getsize(heightmeasurespec);
if (widthspecmode == measurespec.exactly
|| widthspecmode == measurespec.at_most) {
mwidth = widthspecsize;
} else {
mwidth = 0 ;
}
if (heightspecmode == measurespec.at_most
|| heightspecmode == measurespec.unspecified) {
mheight = diptopx( 15 );
} else {
mheight = heightspecsize;
}
setmeasureddimension(mwidth, mheight);
}
}
|
demo:progressviewdemo.rar
以上内容就是实现android自定义进度条渐变圆形的代码,希望对大家有所帮助。