欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-04-06 13:29:39
本文实例为大家分享了android自定义圆弧进度条数字变化的具体代码,供大家参考,具体内容如下效果如下:思路:一个内环圆弧和一个外环圆弧,因为有一个圆圈是在圆弧上做圆周运动,所以在画圆的时候必须要得到...

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

效果如下:

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 进度条