观心静

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

声明版权

本文来自博客园,作者:观心静 ,转载请注明原文链接:https://www.cnblogs.com/guanxinjing/p/12069671.html

本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。

前言

  一个实现,空心圆环的自定义View,已经封装完好,可以直接使用。

 

效果图

 

代码

 

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.SweepGradient;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.ColorInt;
import androidx.annotation.Nullable;

public class RingProgressBar extends View {
    private Paint mPaint;
    private int mBgRingColor = Color.BLACK;
    private int mProgressRingColor = Color.RED;
    private int mBgRingWidth = 20;
    private int mProgressRingWidth = 20;
    private int mMax = 100;
    private int mCurrentProgress = 0;
    private int width = 0;
    private int height = 0;
    private int [] mGradientColors;
    private float [] mGradientColorsPositions;
    private boolean mIsGradientColors = false;


    public RingProgressBar(Context context) {
        super(context);
    }

    public RingProgressBar(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint();
    }

    public RingProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mPaint = new Paint();
    }

    public RingProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        mPaint = new Paint();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawBgRing(canvas);
        drawProgressRing(canvas);
    }

    /**
     * 测量尺寸
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = MeasureSpec.getSize(widthMeasureSpec);
        height = MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(width, height);
    }

    public void setBgRing(@ColorInt int bgRingColor, int ringWidth) {
        mBgRingColor = bgRingColor;
        mBgRingWidth = dip2px(ringWidth);
        postInvalidate();
    }

    /**
     * 设置进度颜色
     * @param progressRingColor
     * @param ringWidth
     */
    public void setProgressRing(@ColorInt int progressRingColor, int ringWidth) {
        mProgressRingColor = progressRingColor;
        mProgressRingWidth = dip2px(ringWidth);
        mIsGradientColors = false;
        postInvalidate();
    }

    /**
     * 设置进度渐变颜色
     * @param gradientColors 渐变颜色组 例如: int [] colors = new int[]{0xff56F9D0,0xFF4194F9};
     *                       <p>
     *                        这里有一个需要注意的点,因为 mPaint.setStrokeCap(Paint.Cap.ROUND);
     *                        这个属性会导致开始的半圆颜色特别突兀,所以这里建议将颜色组的第一个开始颜色也添加结束颜色里,举例如下:
     *                        new int[]{Color.RED,Color.BLUE,Color.RED};
     *                        并且位置推荐设置为 (0f, 0.95f,1f)
     *                       </p>
     * @param gradientColorsPositions 颜色渐变点 例如: float [] floats = new float[]{0,0.5f};
     * @ps 颜色组和渐变点组 数量需要一致
     */
    public void setProgressRing(int ringWidth, int [] gradientColors,float [] gradientColorsPositions){
        mProgressRingWidth = dip2px(ringWidth);
        mIsGradientColors = true;
        mGradientColors = gradientColors;
        mGradientColorsPositions = gradientColorsPositions;
        postInvalidate();
    }

    /**
     * 设置最大值
     *
     * @param max
     */
    public void setMax(int max) {
        mMax = max;
        postInvalidate();

    }

    /**
     * 设置进度
     *
     * @param progress
     */
    public void setProgress(int progress) {
        mCurrentProgress = progress;
        postInvalidate();   //请求失效,重新绘制

    }

    /**
     * 绘制背景环
     * @param canvas
     */
    private void drawBgRing(Canvas canvas) {
        mPaint.setColor(mBgRingColor);      //设置画笔颜色
        mPaint.setStyle(Paint.Style.STROKE);//设置画笔为描边
        mPaint.setStrokeWidth(mBgRingWidth);//设置描边宽度
        mPaint.setStrokeCap(Paint.Cap.BUTT);//设置画笔收笔类型
        mPaint.setAntiAlias(true);          //抗锯齿
        canvas.drawCircle(width / 2, height / 2, (width - mBgRingWidth) / 2, mPaint);   //画圆形
        mPaint.reset();
    }

    /**
     * 绘制进度环
     * @param canvas
     */
    private void drawProgressRing(Canvas canvas) {
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        int x = getWidth()/2;
        int y = getHeight()/2;
        if (mIsGradientColors){
            SweepGradient sg = new SweepGradient(x,y,mGradientColors,mGradientColorsPositions);
            Matrix matrix = new Matrix();
            matrix.preRotate(270,x,y);
            sg.setLocalMatrix(matrix);
            mPaint.setShader(sg);
        } else {
            mPaint.setColor(mProgressRingColor);
        }
        mPaint.setStrokeWidth(mProgressRingWidth);
        mPaint.setAntiAlias(true);
        RectF rectF = new RectF();
        rectF.left = 0 + mProgressRingWidth / 2;
        rectF.right = width - mProgressRingWidth / 2;
        rectF.top = 0 + mProgressRingWidth / 2;
        rectF.bottom = height - mProgressRingWidth / 2;
        float progress = 0;
        if (mCurrentProgress < mMax) {
            float proportion = (float) 360 / (float) mMax;
            progress = mCurrentProgress * proportion;
        } else {
            progress = 360;
        }
        canvas.drawArc(rectF, 270, progress, false, mPaint);    //画圆弧
        mPaint.reset();
    }

    /**
     * 根据手机分辨率从DP转成PX
     * @param dpValue
     * @return
     */
    public int dip2px(float dpValue) {
        float scale = getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}

 

 

 

 

 

END

posted on 2019-12-19 19:27  观心静  阅读(834)  评论(0编辑  收藏  举报