自定义VIew——漂亮的圆形进度条

package com.example.firstapp;

import java.text.DecimalFormat;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

/**
 * 自定义圆形进度条思路
 * 
 * 1.先画外圆,再画弧度,
 * 2.然后在画内圆
 * 3.画文本信息
 * 形成一个叠加的效果
 */
public class MyProgressBar extends View {
	private FontMetrics fm;
	private Paint paint;
	/**内圆半径*/
	private int inRadius;
	/**外圆半径*/
	private int outRadius;
	/**文字的颜色*/
	private int textColor=Color.rgb(20,131,214);
	/**内圆的颜色*/
	private int inRdColor=Color.WHITE;
	/**外圆的颜色*/
	private int outRdColor=Color.LTGRAY;
	/**进度条的颜色*/
	private int proColor=Color.rgb(20,131,214);
	/**进度的最大值*/
	private int max;
	/**当前进度条的值*/
	private int progress;
	/**文字的大小*/
	private int textSize=50;
	

	public MyProgressBar(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	private void init() {
		paint = new Paint();
	}

	/***
	 * 设置内圆的半径
	 * 
	 * @param radius
	 */
	public void setInRadius(int radius) {
		this.inRadius = radius;
	}

	/***
	 * 设置外圆的半径
	 * 
	 * @param radius
	 */
	public void setOutRadius(int radius) {
		this.outRadius = radius;
	}

	/**
	 * 设置进度条的颜色 默认蓝色
	 * 
	 * @param color
	 */
	public void setColor(int color) {
		this.textColor=color;
	}

	/***
	 * 设置文字的颜色值 默认蓝色
	 * 
	 * @param color
	 */
	public void setTextColor(int color) {
		this.textColor=color;
	}

	/***
	 * 设置进度条的最大值
	 * @param max
	 */
	public void setMax(int max) {
		this.max = max;
	}

	/***
	 * 设置当前进度条的进度值
	 * @param progress
	 */
	public void setProgress(int progress) {
		this.progress=progress;
		//设置进度之后,要求UI强制进行重绘
		postInvalidate();
	}
	
	/**
	 * 设置文字的大小
	 * @param size
	 */
	public void setTextSize(int size){
		this.textSize=size;
	}
	
	
	@SuppressLint("DrawAllocation")
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		// 获取控件的中心点
		int cx = getWidth() / 2;
		int cy = getHeight() / 2;

		/***
		 * 1.画外圆
		 */
		paint.setAntiAlias(true);// 设置画笔抗锯齿效果
		paint.setColor(this.outRdColor);
		canvas.drawCircle(cx, cy, this.outRadius, paint);
		

		/***
		 * 2.画弧度
		 */
		paint.setColor(this.proColor);
//		paint.setARGB(0, 25, 63, 155);
		// 圆形进度条的宽度就是外圆的半径减去内圆的半径
		paint.setStrokeWidth(outRadius - inRadius);
		paint.setStyle(Paint.Style.STROKE);//设置弧度外填充

		/**
		 * 用于定义的圆弧的形状和大小的界限, 界限的计算:就是以外圆的正切圆的方式计算出,左上,右下的坐标值
		 * 有了中心点的坐标值cx,cy,也有了半径r那么
		 * 
		 * left=cx-外圆的半径 
		 * top=cy-外圆的半径 
		 * right=cx+外圆的半径 
		 * bottom=cy+外圆的半径
		 * 
		 * 但这里要考虑一个问题是画笔有他本身的宽度,根据上面的思路把画笔的宽度问题,重新计算出圆弧的范围
		 */

		int middle = (int) (paint.getStrokeWidth() / 2);
		RectF oval = new RectF(cx - outRadius + middle, cy - outRadius + middle, cx + outRadius - middle, cy
				+ outRadius - middle);
		canvas.drawArc(oval, 0, 360 * this.progress / this.max, false, paint); // 根据进度画圆弧

		/***
		 * 3.画内圆
		 */
		paint.setStyle(Paint.Style.FILL);
		paint.setColor(this.inRdColor);
		canvas.drawCircle(cx, cy, this.inRadius, paint);
		
		
		/***
		 *4. 绘制文本
		 */
		paint.setColor(this.textColor);
		paint.setStrokeWidth(5);
		paint.setTextSize(this.textSize);
		fm = paint.getFontMetrics();
		
		//保留两位小数
		DecimalFormat df = new DecimalFormat("#.00");
		String numText=df.format(this.progress*1.0/max*100);
		// 测量文本的宽度
		float textWidth = paint.measureText(numText) / 2;
		Log.d("progress", progress+"");
		float textCenterVerticalBaselineY = getHeight() / 2 - fm.descent + (fm.descent - fm.ascent) / 2;
		
		canvas.drawText(numText, cx - textWidth, textCenterVerticalBaselineY, paint);
	}

}


  

原文地址:https://www.cnblogs.com/tianshidechibang234/p/4428699.html