Android开发自定义圆形进度条

一、效果图

圆形进度条.png

二、自定义思路步骤分析

  • 确定控件的大小,宽高相等
    setMeasuredDimension(mViewSize,mViewSize);
  • 画背景圆环
    float radius = mViewSize/2 - ringWidth/2;
    canvas.drawCircle(mViewSize/2,mViewSize/2,radius,mBackgroundPaint);
  • 画当前进度圆弧
    canvas.drawArc
  • 将坐标原点移到控件中心
    canvas.translate(getWidth()/2,getHeight()/2);
  • 绘制进度数字
    canvas.drawText

三、完整的源代码

public class CircleProgressBar extends View {
private Paint mBackgroundPaint;//背景画笔
private Paint mProgressPaint;//进度画笔
private Paint textPaint; //文字画笔

private int mViewSize;

private int mMaxProgress = 100;//最大进度
private int mProgress = 0;//当前进度

private float ringWidth;//圆环宽度

public CircleProgressBar(Context context) {
    this(context, null);
}

public CircleProgressBar(Context context, AttributeSet attrs) {
    super(context, attrs);

    int bgColor = context.getResources().getColor(R.color.c_f2efef);
    int currentColor = context.getResources().getColor(R.color.m_red);
    ringWidth = UtilHelper.INSTANCE.dip2px(context,4f);
    if (attrs != null){
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressBar,0,0);
        bgColor = ta.getColor(R.styleable.CircleProgressBar_cp_bg_color,context.getResources().getColor(R.color.c_f2efef));
        currentColor = ta.getColor(R.styleable.CircleProgressBar_cp_current_color,context.getResources().getColor(R.color.m_red));
        ringWidth = ta.getDimension(R.styleable.CircleProgressBar_cp_width,UtilHelper.INSTANCE.dip2px(context,4f));
        ta.recycle();
    }

    mBackgroundPaint = new Paint();
    mBackgroundPaint.setAntiAlias(true);
    mBackgroundPaint.setColor(bgColor);
    mBackgroundPaint.setStyle(Paint.Style.STROKE);
    mBackgroundPaint.setStrokeWidth(ringWidth);

    mProgressPaint = new Paint();
    mProgressPaint.setAntiAlias(true);
    mProgressPaint.setColor(currentColor);
    mProgressPaint.setStyle(Paint.Style.STROKE);
    mProgressPaint.setStrokeWidth(ringWidth);
    //开始和结尾两端圆角
    mProgressPaint.setStrokeCap(Paint.Cap.ROUND);

    textPaint = new Paint();
    textPaint.setAntiAlias(true);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    int mViewWidth = MeasureSpec.getSize(widthMeasureSpec);
    int mViewHeight = MeasureSpec.getSize(heightMeasureSpec);

    if (mViewWidth > mViewHeight){
        mViewSize = mViewWidth;
    } else {
        mViewSize = mViewHeight;
    }
    setMeasuredDimension(mViewSize,mViewSize);

}

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

    //画背景圆环
    float radius = mViewSize/2 - ringWidth/2;
    canvas.drawCircle(mViewSize/2,mViewSize/2,radius,mBackgroundPaint);

    //画当前进度
    float sweepAngle = 0;
    if (mMaxProgress > 0) {
        sweepAngle = 360*mProgress/mMaxProgress;
    }
    RectF rectF = new RectF(ringWidth/2,ringWidth/2,mViewSize-ringWidth/2,mViewSize-ringWidth/2);
    canvas.drawArc(rectF,-90,sweepAngle,false,mProgressPaint);

    //中心写进度文字
    //将坐标原点移到控件中心
    canvas.translate(getWidth()/2,getHeight()/2);
    //先绘制当前的进度
    textPaint.setTextSize(UtilHelper.INSTANCE.dip2px(getContext(),16));
    textPaint.setColor(getContext().getResources().getColor(R.color.m_red));
    //当前文字宽
    float textCurrentWidth = textPaint.measureText(mProgress+"");

    //绘制总的进度文字
    textPaint.setTextSize(UtilHelper.INSTANCE.dip2px(getContext(),10));
    float textMaxWidth = textPaint.measureText("/"+mMaxProgress);


    textPaint.setTextSize(UtilHelper.INSTANCE.dip2px(getContext(),16));
    float baseLineY = Math.abs(textPaint.ascent() + textPaint.descent()) / 2;
    canvas.drawText(mProgress+"",-(textCurrentWidth+textMaxWidth)/2,baseLineY,textPaint);

    textPaint.setTextSize(UtilHelper.INSTANCE.dip2px(getContext(),10));
    textPaint.setColor(getContext().getResources().getColor(R.color.c_757575));
    canvas.drawText("/"+mMaxProgress,-(textMaxWidth)/2+textCurrentWidth/2,baseLineY,textPaint);
}

/**
* @desc : 设置当前进度条
* @author : congge on 2020/2/18 17:40
**/
public void setmProgress(int mProgress,int mMaxProgress) {
    this.mProgress = mProgress;
    this.mMaxProgress = mMaxProgress;
    invalidate();
}
}

总结:这是个很好的自定义控件学习范例,还不点个赞!!!

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容