Android实现带数字的圆形进度条(自定义进度条)
程序员文章站
2023-12-19 18:29:46
开发
设计搞了一个带圆形进度的进度条,在github上逛了一圈,发现没有,自己撸吧。
先看界面效果:
主要思路是写一个继承progressbar的自定义view,...
开发
设计搞了一个带圆形进度的进度条,在github上逛了一圈,发现没有,自己撸吧。
先看界面效果:
主要思路是写一个继承progressbar的自定义view,不废话,直接上代码:
package com.fun.progressbarwithnumber; import android.content.context; import android.content.res.typedarray; import android.graphics.canvas; import android.graphics.paint; import android.graphics.rectf; import android.util.attributeset; import android.util.typedvalue; import android.widget.progressbar; public class horizontalprogressbarwithnumber extends progressbar { private static final int default_text_size = 10; private static final int default_text_color = 0xfffc00d1; private static final int default_color_unreached_color = 0xffd3d6da; private static final int default_height_reached_progress_bar = 2; private static final int default_height_unreached_progress_bar = 2; private static final int default_circle_color = 0xff3f51b5; protected paint mpaint = new paint(); // 字体颜色 protected int mtextcolor = default_text_color; // 字体大小 protected int mtextsize = sp2px(default_text_size); // 覆盖进度高度 protected int mreachedprogressbarheight = dp2px(default_height_reached_progress_bar); // 覆盖进度颜色 protected int mreachedbarcolor = default_text_color; // 未覆盖进度高度 protected int munreachedprogressbarheight = dp2px(default_height_unreached_progress_bar); // 未覆盖进度颜色 protected int munreachedbarcolor = default_color_unreached_color; // 圆的颜色 protected int mcirclecolor = default_circle_color; protected int mrealwidth; protected boolean mifdrawtext = true; protected boolean mifdrawcircle = true; protected static final int visible = 0; public horizontalprogressbarwithnumber(context context, attributeset attrs) { this(context, attrs, 0); } public horizontalprogressbarwithnumber(context context, attributeset attrs, int defstyle) { super(context, attrs, defstyle); obtainstyledattributes(attrs); mpaint.settextsize(mtextsize); mpaint.setcolor(mtextcolor); mpaint.setantialias(true); } private void obtainstyledattributes(attributeset attrs) { // 获取自定义属性 final typedarray attributes = getcontext().obtainstyledattributes(attrs, r.styleable.horizontalprogressbarwithnumber); mtextcolor = attributes.getcolor(r.styleable.horizontalprogressbarwithnumber_progress_text_color, default_text_color); mtextsize = (int) attributes.getdimension(r.styleable.horizontalprogressbarwithnumber_progress_text_size, mtextsize); mcirclecolor = attributes.getcolor(r.styleable.horizontalprogressbarwithnumber_progress_circle_color, default_circle_color); mreachedbarcolor = attributes.getcolor(r.styleable.horizontalprogressbarwithnumber_progress_reached_color, mtextcolor); munreachedbarcolor = attributes.getcolor(r.styleable.horizontalprogressbarwithnumber_progress_unreached_color, default_color_unreached_color); mreachedprogressbarheight = (int) attributes.getdimension(r.styleable.horizontalprogressbarwithnumber_progress_reached_bar_height, mreachedprogressbarheight); munreachedprogressbarheight = (int) attributes.getdimension(r.styleable.horizontalprogressbarwithnumber_progress_unreached_bar_height, munreachedprogressbarheight); int textvisible = attributes.getint(r.styleable.horizontalprogressbarwithnumber_progress_text_visibility, visible); if (textvisible != visible) { mifdrawtext = false; } attributes.recycle(); int left = (int) (mreachedprogressbarheight * 0.8), right = (int) (mreachedprogressbarheight * 0.8); int top = (int) (mreachedprogressbarheight * 0.3 + dp2px(1)), bottom = (int) (mreachedprogressbarheight * 0.3 + dp2px(1)); setpadding(left, top, right, bottom); } @override protected synchronized void onmeasure(int widthmeasurespec, int heightmeasurespec) { int width = measurespec.getsize(widthmeasurespec); int height = measureheight(heightmeasurespec); setmeasureddimension(width, height); mrealwidth = getmeasuredwidth() - getpaddingright() - getpaddingleft(); } private int measureheight(int measurespec) { int result; int specmode = measurespec.getmode(measurespec); int specsize = measurespec.getsize(measurespec); if (specmode == measurespec.exactly) { result = specsize; } else { float textheight = (mpaint.descent() - mpaint.ascent()); result = (int) (getpaddingtop() + getpaddingbottom() + math.max( math.max(mreachedprogressbarheight, munreachedprogressbarheight), math.abs(textheight))); if (specmode == measurespec.at_most) { result = math.min(result, specsize); } } return result; } @override protected synchronized void ondraw(canvas canvas) { canvas.save(); canvas.translate(getpaddingleft(), getheight() / 2); boolean noneedbg = false; float radio = getprogress() * 1.0f / getmax(); float progressposx = (int) (mrealwidth * radio); string text = getprogress() + "%"; float textwidth = mpaint.measuretext(text); float textheight = (mpaint.descent() + mpaint.ascent()) / 2; float radius = (mreachedprogressbarheight + getpaddingbottom() + getpaddingtop()) / 2; // 覆盖的进度 float endx = progressposx; if (endx > -1) { mpaint.setcolor(mreachedbarcolor); rectf rectf = new rectf(0, 0 - getpaddingtop() - getpaddingbottom(), endx, mreachedprogressbarheight - getpaddingbottom()); canvas.drawroundrect(rectf, 25, 25, mpaint); } // 未覆盖的进度 if (!noneedbg) { float start = progressposx; mpaint.setcolor(munreachedbarcolor); rectf rectf = new rectf(start, 0 - getpaddingtop() - getpaddingbottom(), mrealwidth + getpaddingright() - radius, mreachedprogressbarheight - getpaddingbottom()); canvas.drawroundrect(rectf, 25, 25, mpaint); } // 圆 if (mifdrawcircle) { mpaint.setcolor(mcirclecolor); canvas.drawcircle(progressposx, 0, radius, mpaint); } // 文本 if (mifdrawtext) { mpaint.setcolor(mtextcolor); canvas.drawtext(text, progressposx - textwidth / 2, -textheight, mpaint); } canvas.restore(); } /** * dp 2 px */ protected int dp2px(int dpval) { return (int) typedvalue.applydimension(typedvalue.complex_unit_dip, dpval, getresources().getdisplaymetrics()); } /** * sp 2 px */ protected int sp2px(int spval) { return (int) typedvalue.applydimension(typedvalue.complex_unit_sp, spval, getresources().getdisplaymetrics()); } }
使用
在布局文件中加入:
<com.fun.progressbarwithnumber.horizontalprogressbarwithnumber android:id="@+id/hpbwn" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" fun:progress_circle_color="#ff000000" fun:progress_reached_bar_height="20dp" fun:progress_reached_color="#ffff4081" fun:progress_text_color="#ffffffff" fun:progress_text_size="14sp" fun:progress_unreached_bar_height="20dp" fun:progress_unreached_color="#ffbcb4e8" />
progress_reached_bar_height:当前进度的高度
progress_unreached_bar_height:剩余进度的高度
progress_text_size:圆圈内文字的大小
注意:
当前进度和剩余进度的高度要一致,圆圈大小和圆圈内文字的大小要配合java代码调整。
项目源码:
https://github.com/hfrommane/progressbarwithnumber
以上所述是小编给大家介绍的android实现带数字的圆形进度条(自定义进度条),希望对大家有所帮助