Android自定义圆弧进度条加数字动态变化

2022-07-30,,,,

本文实例为大家分享了android自定义圆弧进度条数字变化的具体代码,供大家参考,具体内容如下

效果如下:

思路:一个内环圆弧和一个外环圆弧,因为有一个圆圈是在圆弧上做圆周运动,所以在画圆的时候必须要得到圆弧上的各个点的坐标,这里其实就用到了pathmeasure这个类,可以帮我们拿到这些点,在画圆弧的时候也理所应当的要使用path,然后根据外界动态的传值进行重绘就能达到动态的效果

代码如下:

public class progresspathrainbow extends view {
 private paint outpaint;
 private paint innerpaint;
 private paint mtextpaint;
 private paint mrmbtextpaint;
 private int mborderwidth = 40;
 private int mcircleradius = 40;
 private int mcurrentprogress = 0;
 private int mmaxprogress = 0;
 private int startangle = 180;

 private int sweepangels = 180;
 private paint mcirclepaint;
 private string rmb = "¥";
 private string currenttext = "0.0";

 public void setcurrenttext(string currenttext) {
 this.currenttext = currenttext;
 }

 //储存位置点
 private float[] pos =new float[2];

 public progresspathrainbow(context context) {
 super(context);
 initpaint();
 }

 public progresspathrainbow(context context, @nullable attributeset attrs) {
 super(context, attrs);
 initpaint();
 }

 public progresspathrainbow(context context, @nullable attributeset attrs, int defstyleattr) {
 super(context, attrs, defstyleattr);
 initpaint();
 }

 private void initpaint(){
 outpaint = new paint();
 outpaint.setcolor(0xffececec);
 outpaint.setantialias(true);
 outpaint.setstyle(paint.style.stroke);
 outpaint.setstrokecap(paint.cap.round);
 outpaint.setstrokewidth(mborderwidth);

 //
 innerpaint = new paint();
 innerpaint.setcolor(0xfffba123);
 innerpaint.setantialias(true);
 innerpaint.setstyle(paint.style.stroke);
 innerpaint.setstrokecap(paint.cap.round);
 innerpaint.setstrokewidth(mborderwidth);

 mcirclepaint = new paint();
 mcirclepaint.setcolor(color.white);
 mcirclepaint.setstyle(paint.style.fill);

 mtextpaint = new paint();
 mtextpaint.setantialias(true);
 mtextpaint.setcolor(0xffe5423d);
 mtextpaint.setfakeboldtext(true);
 mtextpaint.settextsize(sizeutils.sp2px(42));


 mrmbtextpaint = new paint();
 mrmbtextpaint.setantialias(true);
 mrmbtextpaint.setcolor(0xffe5423d);
 mrmbtextpaint.settextsize(sizeutils.sp2px(18));

 }

 @override
 protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {

 super.onmeasure(widthmeasurespec, heightmeasurespec);
 int width = measurespec.getsize(widthmeasurespec);
 int height = measurespec.getsize(heightmeasurespec);
 if (width >= height){
 setmeasureddimension(height,height);
 }else {
 setmeasureddimension(width,width);
 }


 }

 @override
 protected void ondraw(canvas canvas) {
 super.ondraw(canvas);

 rectf rectf = new rectf(mborderwidth,mborderwidth,getwidth()-mborderwidth,getheight()-mborderwidth);
 //画内环圆弧
 path outerpath = new path();
 outerpath.arcto(rectf,startangle,sweepangels);
 canvas.drawpath(outerpath,outpaint);
 //画外环圆弧
 path innerpah = new path();
 float percent = (float)mcurrentprogress/mmaxprogress;
 innerpah.arcto(rectf,startangle,percent*sweepangels);
 canvas.drawpath(innerpah,innerpaint);


 //画金额
 string temptext = new bigdecimal(currenttext).multiply(new bigdecimal(percent)).setscale(1, roundingmode.half_up).tostring();
 rect textbounds = new rect();
 mtextpaint.gettextbounds(temptext, 0, temptext.length(), textbounds);
 int dx = getwidth()/2 - textbounds.width()/2;
 // 基线 baseline
 paint.fontmetricsint fontmetrics = mtextpaint.getfontmetricsint();
 int dy = (fontmetrics.bottom - fontmetrics.top)/2 - fontmetrics.bottom;
 int baseline = getheight()/3 + dy;
 canvas.drawtext(temptext,dx,baseline,mtextpaint);

 //画人民币符号

 rect textboundrmbs = new rect();
 mtextpaint.gettextbounds(rmb, 0, rmb.length(), textboundrmbs);
 int dxrmb = dx-50;
 // 基线 baseline
 paint.fontmetricsint fontmetricsrmb = mtextpaint.getfontmetricsint();
 int dyrmb = (fontmetricsrmb.bottom - fontmetricsrmb.top)/2 - fontmetricsrmb.bottom;
 int baselinermb = getheight()/3 + dyrmb;
 canvas.drawtext(rmb,dxrmb,baselinermb,mrmbtextpaint);

 //获取圆弧上点的位置(坐标,画一个圆)
 pathmeasure pathmeasure = new pathmeasure(outerpath,false);
 boolean postan = pathmeasure.getpostan(pathmeasure.getlength() * percent, pos, null);
 canvas.drawcircle(pos[0],pos[1],mcircleradius,mcirclepaint);

 }

 public synchronized void setmcurrentprogress(int mcurrentprogress) {
 this.mcurrentprogress = mcurrentprogress;
 invalidate();
 }

 public synchronized void setmmaxprogress(int mmaxprogress) {
 this.mmaxprogress = mmaxprogress;
 }
}

以上就可以实现这个效果

使用的话可以这样

detailrainbowpr.setmmaxprogress(100);
detailrainbowpr.setcurrenttext("99.9");
valueanimator valueanimator = objectanimator.offloat(0, 100);
 valueanimator.setduration(5000);
 valueanimator.setinterpolator(new decelerateinterpolator());
 valueanimator.addupdatelistener(valueanimator1 -> {
 float step = (float) valueanimator1.getanimatedvalue();
 detailrainbowpr.setmcurrentprogress((int) step);
 });
 valueanimator.start();

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

《Android自定义圆弧进度条加数字动态变化.doc》

下载本文的Word格式文档,以方便收藏与打印。