最近项目中使用到了渐变效果的圆形进度条,网上找了很多渐变效果不够圆滑,两个渐变颜色之间有明显的过渡,或者有些代码画出来的效果过渡不美观,于是自己参照写了一个,喜欢的朋友可以参考或者直接使用。
先上一张效果图,视频录制不太好,不过不影响效果
下面开始介绍实现代码,比较简单,直接贴代码吧
1、声明自定义属性
在项目的valuse文件夹下新建attrs.xml,在里面定义自定义控件需要的属性
2、自定义一个进度条RoundProgres继承view类
package com.blankj.progressring; import android.animation.ValueAnimator; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.SweepGradient; import android.graphics.Typeface; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.animation.LinearInterpolator; import org.jetbrains.annotations.Nullable; /** * 类描述:渐变的圆形进度条 * * @author:lusy * @date :2018/10/17 */ public class RoundProgress extends View { private static final String TAG = "roundProgress"; /** * 背景圆环画笔 */ private Paint bgPaint; /** * 白色标记画笔 */ private Paint iconPaint; /** * 进度画笔 */ private Paint progressPaint; /** * 进度文本画笔 */ private Paint textPaint; /** * 背景圆环的颜色 */ private int bgColor; /** * 线条进度的颜色 */ private int iconColor; private int[] progressColor; /** * 中间进度百分比的字符串的颜色 */ private int textColor; /** * 中间进度百分比的字符串的字体大小 */ private float textSize; /** * 圆环的宽度 */ private float roundWidth; /** * 最大进度 */ private int max; /** * 当前进度 */ private float progress; /** * 是否显示中间的进度 */ private boolean textIsDisplayable; /** * 圆环半径 */ private int mRadius; private int center; private float startAngle = -90; private float currentAngle; private float currentProgress; public RoundProgress(Context context) { this(context, null); } public RoundProgress(Context context, @Nullable AttributeSet attrs) { super(context, attrs); TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundProgress); //获取自定义属性和默认值 bgColor = mTypedArray.getColor(R.styleable.RoundProgress_bgColor, Color.parseColor("#2d2d2d")); icOnColor= mTypedArray.getColor(R.styleable.RoundProgress_lineColor, Color.parseColor("#ffffff")); textColor = mTypedArray.getColor(R.styleable.RoundProgress_textColor, Color.parseColor("#ffffff")); textSize = mTypedArray.getDimension(R.styleable.RoundProgress_textSize, 15); roundWidth = mTypedArray.getDimension(R.styleable.RoundProgress_roundWidth, 5); max = mTypedArray.getInteger(R.styleable.RoundProgress_maxProgress, 100); textIsDisplayable = mTypedArray.getBoolean(R.styleable.RoundProgress_textIsDisplayable, true); progressColor = new int[]{Color.parseColor("#747eff"), Color.parseColor("#0018ff"), Color.TRANSPARENT}; mTypedArray.recycle(); initPaint(); } public RoundProgress(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //测量控件应占的宽高大小,此处非必需,只是为了确保布局中设置的宽高不一致时仍显示完整的圆 int measureWidth = MeasureSpec.getSize(widthMeasureSpec); int measureHeight = MeasureSpec.getSize(heightMeasureSpec); setMeasuredDimension(Math.min(measureWidth, measureHeight), Math.min(measureWidth, measureHeight)); } private void initPaint() { bgPaint = new Paint(); bgPaint.setStyle(Paint.Style.STROKE); bgPaint.setAntiAlias(true); bgPaint.setColor(bgColor); bgPaint.setStrokeWidth(roundWidth); icOnPaint= new Paint(); iconPaint.setStyle(Paint.Style.STROKE); iconPaint.setAntiAlias(true); iconPaint.setColor(iconColor); iconPaint.setStrokeWidth(roundWidth); progressPaint = new Paint(); progressPaint.setStyle(Paint.Style.STROKE); progressPaint.setAntiAlias(true); progressPaint.setStrokeWidth(roundWidth); textPaint = new Paint(); textPaint.setStyle(Paint.Style.STROKE); textPaint.setTypeface(Typeface.DEFAULT_BOLD); textPaint.setAntiAlias(true); textPaint.setColor(textColor); textPaint.setTextSize(textSize); textPaint.setStrokeWidth(0); } @Override protected void onDraw(Canvas canvas) { /** * 画最外层的大圆环 */ //获取圆心的x坐标 center = Math.min(getWidth(), getHeight()) / 2; // 圆环的半径 mRadius = (int) (center - roundWidth / 2); RectF oval = new RectF(center - mRadius, center - mRadius, center + mRadius, center + mRadius); //画背景圆环 canvas.drawArc(oval, startAngle, 360, false, bgPaint); //画进度圆环 drawProgress(canvas, oval); canvas.drawArc(oval, startAngle, currentAngle, false, progressPaint); //画白色圆环 float start = startAngle + currentAngle - 1; canvas.drawArc(oval, start, 3, false, iconPaint); //百分比文字 int percent = (int) (((float) progress / (float) max) * 100); //测量字体宽度,我们需要根据字体的宽度设置在圆环中间 String text = String.valueOf(percent)+"%"; Rect textRect = new Rect(); textPaint.getTextBounds(text, 0, text.length(), textRect); if (textIsDisplayable && percent >= 0) { //画出进度百分比文字 float x = (getWidth() - textRect.width()) / 2; float y = (getHeight() + textRect.height()) / 2; canvas.drawText(text, x, y, textPaint); } if (currentProgress
3、使用自定义进度条view
activity布局文件使用如下,为了方便测试效果,新增进度加、进度减,修改进度条颜色的按钮
<&#63;xml version="1.0" encoding="utf-8"&#63;>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。