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();

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