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自定义圆弧进度条加数字动态变化 的全部内容, 来源链接: utcz.com/p/242884.html

回到顶部