自定义Android六边形进度条(附源码)
程序员文章站
2024-02-22 17:48:37
本文实例讲述了android自定义圆形进度条,分享给大家供大家参考。具体如下:
大家也可以参考这两篇文章进行学习: 《自定义android圆形进度条(附源码)》&nb...
本文实例讲述了android自定义圆形进度条,分享给大家供大家参考。具体如下:
大家也可以参考这两篇文章进行学习: 《自定义android圆形进度条(附源码)》 《android带进度的圆形进度条》
运行效果截图如下:
主要代码:
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文件:
<?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软件编程有所帮助。
推荐阅读
-
自定义Android六边形进度条(附源码)
-
Android自定义漂亮的圆形进度条
-
Android TreeView效果实现方法(附demo源码下载)
-
Android重写TextView实现文字整齐排版的方法(附demo源码下载)
-
Android开发之在程序中时时获取logcat日志信息的方法(附demo源码下载)
-
Android AutoCompleteTextView连接数据库自动提示的方法(附demo源码下载)
-
Android编程基于自定义View实现绚丽的圆形进度条功能示例
-
实例详解Android自定义ProgressDialog进度条对话框的实现
-
Android 自定义ProgressDialog进度条对话框用法详解
-
Android编程实现简易弹幕效果示例【附demo源码下载】