Android环形进度条

mac2025-07-11  3

圆环进度条style属性设置,在res/values/attr.xml中进行声明

<declare-styleable name="CircularProgressView"> <attr name="backWidth" format="dimension" /> <!--背景圆环宽度--> <attr name="progWidth" format="dimension" /> <!--进度圆环宽度--> <attr name="backColor" format="color" /> <!--背景圆环颜色--> <attr name="progColor" format="color" /> <!--进度圆环颜色--> <attr name="progStartColor" format="color" /> <!--进度圆环开始颜色--> <attr name="progFirstColor" format="color" /> <!--进度圆环结束颜色--> <attr name="progress" format="integer" /> <!--圆环进度--> </declare-styleable>

实现环形进度条效果

import android.animation.ValueAnimator import android.annotation.SuppressLint import android.content.Context import android.graphics.* import android.support.annotation.ColorRes import android.support.annotation.Nullable import android.support.v4.content.ContextCompat import android.util.AttributeSet import android.view.View import android.view.animation.OvershootInterpolator class CircularProgressView @JvmOverloads constructor(context: Context, @Nullable attrs: AttributeSet? = null, defStyleAttr: Int = 0) : View(context, attrs, defStyleAttr) { private val mBackPaint: Paint private val mProgPaint: Paint // 绘制画笔 private var mRectF: RectF? = null // 绘制区域 private var mColorArray: IntArray? = null // 圆环渐变色 private var mProgress: Int = 0 // 圆环进度(0-100) // --------------------------------------------------------------------------------------------- /** * 获取当前进度 * * @return 当前进度(0-100) */ /** * 设置当前进度 * * @param progress 当前进度(0-100) */ var progress: Int get() = mProgress set(progress) { this.mProgress = progress invalidate() } init { @SuppressLint("Recycle") val typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircularProgressView) // 初始化背景圆环画笔 mBackPaint = Paint() mBackPaint.setStyle(Paint.Style.STROKE) // 只描边,不填充 mBackPaint.setStrokeCap(Paint.Cap.ROUND) // 设置圆角 mBackPaint.setAntiAlias(true) // 设置抗锯齿 mBackPaint.setDither(true) // 设置抖动 mBackPaint.setStrokeWidth(typedArray.getDimension(R.styleable.CircularProgressView_backWidth, 5f)) mBackPaint.setColor(typedArray.getColor(R.styleable.CircularProgressView_backColor, Color.LTGRAY)) // 初始化进度圆环画笔 mProgPaint = Paint() mProgPaint.setStyle(Paint.Style.STROKE) // 只描边,不填充 mProgPaint.setStrokeCap(Paint.Cap.ROUND) // 设置圆角 mProgPaint.setAntiAlias(true) // 设置抗锯齿 mProgPaint.setDither(true) // 设置抖动 mProgPaint.setStrokeWidth(typedArray.getDimension(R.styleable.CircularProgressView_progWidth, 10f)) mProgPaint.setColor(typedArray.getColor(R.styleable.CircularProgressView_progColor, Color.BLUE)) // 初始化进度圆环渐变色 val startColor = typedArray.getColor(R.styleable.CircularProgressView_progStartColor, -1) val firstColor = typedArray.getColor(R.styleable.CircularProgressView_progFirstColor, -1) if (startColor != -1 && firstColor != -1) mColorArray = intArrayOf(startColor, firstColor) else mColorArray = null // 初始化进度 mProgress = typedArray.getInteger(R.styleable.CircularProgressView_progress, 0) typedArray.recycle() } override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { super.onMeasure(widthMeasureSpec, heightMeasureSpec) val viewWide = getMeasuredWidth() - getPaddingLeft() - getPaddingRight() val viewHigh = getMeasuredHeight() - getPaddingTop() - getPaddingBottom() val mRectLength = ((if (viewWide > viewHigh) viewHigh else viewWide) - if (mBackPaint.getStrokeWidth() > mProgPaint.getStrokeWidth()) mBackPaint.getStrokeWidth() else mProgPaint.getStrokeWidth()).toInt() val mRectL = getPaddingLeft() + (viewWide - mRectLength) / 2 val mRectT = getPaddingTop() + (viewHigh - mRectLength) / 2 mRectF = RectF(mRectL.toFloat(), mRectT.toFloat(), (mRectL + mRectLength).toFloat(), (mRectT + mRectLength).toFloat()) // 设置进度圆环渐变色 if (mColorArray != null && mColorArray!!.size > 1) mProgPaint.setShader(LinearGradient(0f, 0f, 0f, getMeasuredWidth() as Float, mColorArray, null, Shader.TileMode.MIRROR)) } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) canvas.drawArc(mRectF, 0f, 360f, false, mBackPaint) canvas.drawArc(mRectF, 275f, 360f * mProgress / 100f, false, mProgPaint) } /** * 设置当前进度,并展示进度动画。如果动画时间小于等于0,则不展示动画 * * @param progress 当前进度(0-100) * @param animTime 动画时间(毫秒) */ fun setProgress(progress: Int, animTime: Long) { if (animTime <= 0) mProgress = progress else { val animator = ValueAnimator.ofInt(mProgress, progress) animator.addUpdateListener { animation -> mProgress = animation.animatedValue as Int invalidate() } animator.interpolator = OvershootInterpolator() animator.duration = animTime animator.start() } } /** * 设置背景圆环宽度 * * @param width 背景圆环宽度 */ fun setBackWidth(width: Int) { mBackPaint.setStrokeWidth(width as Float) invalidate() } /** * 设置背景圆环颜色 * * @param color 背景圆环颜色 */ fun setBackColor(@ColorRes color: Int) { mBackPaint.setColor(ContextCompat.getColor(getContext(), color)) invalidate() } /** * 设置进度圆环宽度 * * @param width 进度圆环宽度 */ fun setProgWidth(width: Int) { mProgPaint.setStrokeWidth(width as Float) invalidate() } /** * 设置进度圆环颜色 * * @param color 景圆环颜色 */ fun setProgColor(@ColorRes color: Int) { mProgPaint.setColor(ContextCompat.getColor(getContext(), color)) mProgPaint.setShader(null) invalidate() } /** * 设置进度圆环颜色(支持渐变色) * * @param startColor 进度圆环开始颜色 * @param firstColor 进度圆环结束颜色 */ fun setProgColor(@ColorRes startColor: Int, @ColorRes firstColor: Int) { mColorArray = intArrayOf(ContextCompat.getColor(getContext(), startColor), ContextCompat.getColor(getContext(), firstColor)) mProgPaint.setShader(LinearGradient(0f, 0f, 0f, getMeasuredWidth() as Float, mColorArray, null, Shader.TileMode.MIRROR)) invalidate() } /** * 设置进度圆环颜色(支持渐变色) * * @param colorArray 渐变色集合 */ fun setProgColor(@ColorRes colorArray: IntArray?) { if (colorArray == null || colorArray.size < 2) return mColorArray = IntArray(colorArray.size) for (index in colorArray.indices) mColorArray!![index] = ContextCompat.getColor(getContext(), colorArray[index]) mProgPaint.setShader(LinearGradient(0f, 0f, 0f, getMeasuredWidth() as Float, mColorArray, null, Shader.TileMode.MIRROR)) invalidate() } }
最新回复(0)