自定义Android六边形进度条(附源码)

时间:2022-09-20 16:04:16

本文实例讲述了android自定义圆形进度条,分享给大家供大家参考。具体如下:

大家也可以参考这篇文章进行学习: 《自定义android圆形进度条(附源码)》 

运行效果截图如下:

自定义Android六边形进度条(附源码)

主要代码:

?
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
package com.sxc.hexagonprogress;
 
import java.util.random;
import android.content.context;
import android.content.res.colorstatelist;
import android.content.res.resources;
import android.content.res.typedarray;
import android.graphics.canvas;
import android.graphics.color;
import android.graphics.paint;
import android.graphics.paintflagsdrawfilter;
import android.graphics.path;
import android.graphics.rectf;
import android.graphics.typeface;
import android.util.attributeset;
import android.util.log;
import android.view.view;
 
 
/**
 * 六边形带进度的进度条,线程安全的view,可直接在线程中更新进度
 *
 * @author sunxunchao
 *
 */
public class hexagonprogress extends view {
 /**
  * 画笔对象的引用
  */
 private paint paint, mpaint;
 
 /**
  * 画笔路径
  */
 private path path, mpath;
 
 /**
  * 环的颜色
  */
 private int roundcolor;
 
 /**
  * 环进度的颜色
  */
 private int roundprogresscolor;
 
 /**
  * 中间进度百分比的字符串的颜色
  */
 private int textcolor;
 
 /**
  * 中间进度百分比的字符串的字体
  */
 private float textsize;
 
 /**
  * 环的宽度
  */
 private float roundwidth;
 
 /**
  * 最大进度
  */
 private double max;
 
 /**
  * 当前进度
  */
 private double progress;
 /**
  * 是否显示中间的进度
  */
 private boolean textisdisplayable;
 
 /**
  * 进度的风格,实心或者空心
  */
 private int style;
 
 public static final int stroke = 0;
 public static final int fill = 1;
 
 public hexagonprogress(context context) {
  this(context, null);
 }
 
 public hexagonprogress(context context, attributeset attrs) {
  this(context, attrs, 0);
 }
 
 public hexagonprogress(context context, attributeset attrs, int defstyle) {
  super(context, attrs, defstyle);
 
  paint = new paint();
  mpaint = new paint();
 
  typedarray mtypedarray = context.obtainstyledattributes(attrs,
    r.styleable.hexagonprogressbar);
 
  // 获取自定义属性和默认值
  roundcolor = mtypedarray.getcolor(
    r.styleable.hexagonprogressbar_hexagoncolor, color.red);
  roundprogresscolor = mtypedarray.getcolor(
    r.styleable.hexagonprogressbar_hexagonprogresscolor, color.green);
  textcolor = mtypedarray.getcolor(
    r.styleable.hexagonprogressbar_textcolor, color.green);
  textsize = mtypedarray.getdimension(
    r.styleable.hexagonprogressbar_textsize, 15);
  roundwidth = mtypedarray.getdimension(
    r.styleable.hexagonprogressbar_hexagonwidth, 5);
  max = mtypedarray.getinteger(r.styleable.hexagonprogressbar_max, 100);
  textisdisplayable = mtypedarray.getboolean(
    r.styleable.hexagonprogressbar_textisdisplayable, true);
 
  mtypedarray.recycle();
 }
 
 @override
 protected void ondraw(canvas canvas) {
  super.ondraw(canvas);
 
  /**
   * 画外六边形
   */
  int centre = getwidth() / 2;// 中心坐标
  int radius = (int) (centre - roundwidth / 2);// 六边形边长
  mpaint.setcolor(roundcolor); // 设置圆环的颜色
  mpaint.setstyle(paint.style.stroke); // 设置空心
  mpaint.setstrokewidth(roundwidth); // 设置圆环的宽度
  mpaint.setantialias(true); // 消除锯齿
  mpath = new path();//设置路径
  // 第一个点坐标(centre-radius, getheight()/2)
  // 第二个点坐标(centre-radius/2,getheight()/2-math.sqrt(3)*radius/2)
  // 第三个点坐标(centre+radius/2,getheight()/2-math.sqrt(3)*radius/2)
  // 第四个点坐标(centre+radius,getheight()/2)
  // 第五个点坐标 (centre+radius/2,math.sqrt(3)*radius/2+getheight()/2)
  // 第六个点坐标 (centre-radius/2,math.sqrt(3)*radius/2+getheight()/2)
  mpath.moveto(centre - radius, centre); // a
  mpath.lineto(centre - radius / 2, (float) (centre - math.sqrt(3)* radius / 2));// b
  mpath.lineto(centre + radius / 2, (float) (centre - math.sqrt(3)* radius / 2));// c
  mpath.lineto(centre + radius, centre);// d
  mpath.lineto(centre + radius / 2,(float) ((math.sqrt(3) * radius / 2) + centre));// e
  mpath.lineto(centre - radius / 2,(float) ((math.sqrt(3) * radius / 2) + centre));// f
  mpath.close();
  canvas.drawpath(mpath, mpaint);
 
  /**
   * 画进度百分比
   */
  mpaint.setstrokewidth(0);
  mpaint.setcolor(textcolor);
  mpaint.settextsize(textsize);
  mpaint.settypeface(typeface.default_bold); // 设置字体
  int percent = (int) (((float) progress / (float) max) * 100); // 中间的进度百分比,先转换成float在进行除法运算,不然都为0
  float textwidth = mpaint.measuretext(percent + "%"); // 测量字体宽度,我们需要根据字体的宽度设置在圆环中间
 
  if (textisdisplayable && style == stroke) {
   canvas.drawtext(percent + "%", centre - textwidth / 2, centre
     + textsize / 2, mpaint); // 画出进度百分比
  }
 
  /**
   * 画六边形进度
   */
 
  path = new path();
  paint.setstrokewidth(roundwidth); // 设置圆环的宽度
  paint.setcolor(roundprogresscolor); // 设置进度的颜色
  paint.setantialias(true);
 
  double k= (progress*6) / max;
 
  paint.setstyle(paint.style.stroke);
   if (k <= 1|| k==0) {
    path.moveto(centre + radius, centre);
    path.lineto((float)(centre+radius-k*radius/2), (float) (centre+k*radius*math.sqrt(3)/2));
   }
   else if (k>1&&k<=2) {
    path.moveto(centre + radius, centre);
    path.lineto(centre + radius / 2, (float) ((math.sqrt(3) * radius / 2) + centre));
    path.lineto((float) (centre+1.5*radius-k*radius), (float) (centre+0.5*math.sqrt(3)*radius));
   }else if (k>2&&k<=3) {
    path.moveto(centre + radius, centre);
    path.lineto(centre + radius / 2, (float) ((math.sqrt(3) * radius / 2) + centre));
    path.lineto(centre - radius / 2, (float) ((math.sqrt(3) * radius / 2) + centre));
    path.lineto((float)(centre+0.5*radius-0.5*radius*k), (float) (centre+1.5*math.sqrt(3)*radius-0.5*k*radius*math.sqrt(3)));
   }else if (k>3&&k<=4) {
    path.moveto(centre + radius, centre);
    path.lineto(centre + radius / 2, (float) ((math.sqrt(3) * radius / 2) + centre));
    path.lineto(centre - radius / 2, (float) ((math.sqrt(3) * radius / 2) + centre));
    path.lineto(centre-radius, centre);
    path.lineto((float)(centre-radius+0.5*k*radius-1.5*radius), (float) (centre-0.5*(k-3)*radius*math.sqrt(3)));
   }else if (k>4&&k<=5) {
    path.moveto(centre + radius, centre);
    path.lineto(centre + radius / 2, (float) ((math.sqrt(3) * radius / 2) + centre));
    path.lineto(centre - radius / 2, (float) ((math.sqrt(3) * radius / 2) + centre));
    path.lineto(centre - radius, centre);
    path.lineto(centre - radius / 2, (float) (centre - math.sqrt(3)* radius / 2));
    path.lineto((float) ((k-4)*radius+centre-0.5*radius),(float) (centre - math.sqrt(3)* radius / 2));
   }else if (k>5&&k<6) {
    path.moveto(centre + radius, centre);
    path.lineto(centre + radius / 2, (float) ((math.sqrt(3) * radius / 2) + centre));
    path.lineto(centre - radius / 2, (float) ((math.sqrt(3) * radius / 2) + centre));
    path.lineto(centre - radius, centre);
    path.lineto(centre - radius / 2, (float) (centre - math.sqrt(3)* radius / 2));
    path.lineto(centre + radius / 2,(float) (centre - math.sqrt(3)* radius / 2));
    path.lineto((float)(centre+0.5*radius+0.5*(k-5)*radius),(float) (centre-0.5*math.sqrt(3)*radius+0.5*math.sqrt(3)*(k-5)*radius));
   }else {
    path.moveto(centre + radius, centre);
    path.lineto(centre + radius / 2, (float) ((math.sqrt(3) * radius / 2) + centre));
    path.lineto(centre - radius / 2, (float) ((math.sqrt(3) * radius / 2) + centre));
    path.lineto(centre - radius, centre);
    path.lineto(centre - radius / 2, (float) (centre - math.sqrt(3)* radius / 2));
    path.lineto(centre + radius / 2,(float) (centre - math.sqrt(3)* radius / 2));
    path.lineto(centre + radius , centre);
    path.close();
   }
 
   canvas.drawpath(path, paint);
 
 }
 
 public synchronized double getmax() {
  return max;
 }
 
 /**
  * 设置进度的最大值
  *
  * @param max
  */
 public synchronized void setmax(int max) {
  if (max < 0) {
   throw new illegalargumentexception("max not less than 0");
  }
  this.max = max;
 }
 
 /**
  * 获取进度.需要同步
  *
  * @return
  */
 public synchronized double getprogress() {
  return progress;
 }
 
 /**
  * 设置进度,此为线程安全控件,由于考虑多线的问题,需要同步 刷新界面调用postinvalidate()能在非ui线程刷新
  *
  * @param progress
  */
 public synchronized void setprogress(double progress) {
  if (progress < 0) {
   throw new illegalargumentexception("progress not less than 0");
  }
  if (progress > max) {
   progress = max;
  }
  if (progress <= max) {
   this.progress = progress;
   postinvalidate();
  }
 
 }
 
 public int getcriclecolor() {
  return roundcolor;
 }
 
 public void setcriclecolor(int criclecolor) {
  this.roundcolor = criclecolor;
 }
 
 public int getcricleprogresscolor() {
  return roundprogresscolor;
 }
 
 public void setcricleprogresscolor(int cricleprogresscolor) {
  this.roundprogresscolor = cricleprogresscolor;
 }
 
 public int gettextcolor() {
  return textcolor;
 }
 
 public void settextcolor(int textcolor) {
  this.textcolor = textcolor;
 }
 
 public float gettextsize() {
  return textsize;
 }
 
 public void settextsize(float textsize) {
  this.textsize = textsize;
 }
 
 public float getroundwidth() {
  return roundwidth;
 }
 
 public void setroundwidth(float roundwidth) {
  this.roundwidth = roundwidth;
 }
 
}

在values中新建一个attrs.xml文件:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="utf-8"?>
<resources>
 <declare-styleable name="hexagonprogressbar">
  <attr name="hexagoncolor" format="color"/>
  <attr name="hexagonprogresscolor" format="color"/>
  <attr name="hexagonwidth" format="dimension"></attr>
  <attr name="textcolor" format="color" />
  <attr name="textsize" format="dimension" />
  <attr name="max" format="integer"></attr>
  <attr name="textisdisplayable" format="boolean"></attr>
  <!-- <attr name="style">
   <enum name="stroke" value="0"></enum>
   <enum name="fill" value="1"></enum>
  </attr> -->
 </declare-styleable>
</resources>

项目免费下载: 《android六边形进度条》

希望本文所述对大家学习android软件编程有所帮助。