效果图
或者是这种效果:
这两种效果其实在画的时候分三部分。
1 先画最外层的圆形。
2 画中间的扇形。
3 画显示进度的百分比文字。
1 自定义属性
<resources>
<declare-styleable name="CostomProgressBar">
<!--扇形颜色-->
<attr name="roundProgressColor" format="color"></attr>
<!--圆环的颜色-->
<attr name="roundColor" format="color"></attr>
<!--圆环的宽度-->
<attr name="roundWidth" format="dimension"></attr>
<!--文字颜色-->
<attr name="textColor" format="color"></attr>
<!--文字大小-->
<attr name="textSize" format="integer"></attr>
<!--最大进度-->
<attr name="max" format="integer"></attr>
<!--是否显示文字-->
<attr name="textShow" format="boolean"></attr>
<!--扇形样式 -->
<attr name="style">
<enum name="STROKE" value="0"></enum>
<enum name="FILL" value="1"></enum>
</attr>
</declare-styleable>
</resources>
2 自定义控件加载属性
public class CostomProgressBar extends View {
/**
* 画笔
*/
private Paint mPaint;
/**
* 进度的最大值
*/
private int max;
/**
*
*/
private int roundColor;
private int roundProgressColor;
/**
* 文字颜色
*/
private int textColor;
/**
* 文字大小
*/
private int textSize;
/**
*
*/
private float roundWidth;
private boolean textShow;
private int style;
/**
* 当前的进度
*/
private int progress;
private static final int STROKE = 0;
private static final int FILL = 1;
public CostomProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint();
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CostomProgressBar);
max = typedArray.getInteger(R.styleable.CostomProgressBar_max, 100);
roundWidth = typedArray.getDimension(R.styleable.CostomProgressBar_roundWidth,10);
roundColor = typedArray.getColor(R.styleable.CostomProgressBar_roundColor, Color.RED);
roundProgressColor = typedArray.getColor(R.styleable.CostomProgressBar_roundProgressColor, Color.BLUE);
textColor = typedArray.getColor(R.styleable.CostomProgressBar_textColor, Color.GREEN);
textSize = typedArray.getInteger(R.styleable.CostomProgressBar_textSize, 55);
textShow = typedArray.getBoolean(R.styleable.CostomProgressBar_textShow, true);
style = typedArray.getInt(R.styleable.CostomProgressBar_style, 0);
typedArray.recycle();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int center = getWidth() / 2; //中心坐标点
//1 画圆环
float radius = center - roundWidth / 2; //半径
mPaint.setColor(roundColor);
mPaint.setStyle(Paint.Style.STROKE);//设置空心
mPaint.setStrokeWidth(roundWidth); //圆环的宽度
mPaint.setAntiAlias(true);
canvas.drawCircle(center, center, radius, mPaint);
//2 画圆弧 矩形区域 定义圆弧的形状大小
RectF oval = new RectF(center - radius, center - radius, center + radius, center + radius);
mPaint.setColor(roundProgressColor);
mPaint.setStrokeWidth(roundWidth);
switch (style) {
case STROKE:
mPaint.setStyle(Paint.Style.STROKE);
canvas.drawArc(oval, 0, 360 * progress / max, true, mPaint);
break;
case FILL:
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
if (progress != 0) {
canvas.drawArc(oval, 0, 360 * progress / max, true, mPaint);
}
break;
}
//3 画进度百分比
mPaint.reset();
mPaint.setColor(textColor);
mPaint.setTextSize(textSize);
mPaint.setTypeface(Typeface.DEFAULT_BOLD);
int persent = (int) (progress / (float) max * 100);
float centerX = (getWidth() - mPaint.measureText(persent + "%")) / 2f;
float centerY = getWidth() / 2f - (mPaint.descent() + mPaint.ascent()) / 2f;
if (textShow && persent != 0 && style == STROKE) {
canvas.drawText(persent + "%", centerX, centerY, mPaint);
}
}
public void setProgress(int progress) {
if (progress < 0) {
throw new IllegalArgumentException("progress不能小于0");
}
if (progress > max) {
progress = max;
}
if (progress <= max) {
this.progress = progress;
postInvalidate();
}
}
}
3 引入自定义控件 设置属性
下面的效果是之前的第二图图
<com.yeliang.app04_costomprogressbar.CostomProgressBar
android:id="@+id/progressbar"
android:layout_width="100dip"
android:layout_height="100dip"
app:roundColor="#000"
app:roundProgressColor="#000"
app:roundWidth="2dp"
app:style="STROKE"
app:textColor="#000000"
app:textSize="18" />
第一张图需要改为如下属性
app:style="FILL"
4 在客户端不断地更新进度
private CostomProgressBar progressBar;
private int progress; //模拟进度
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = (CostomProgressBar) findViewById(R.id.progressbar);
progressBar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
progress = 0;
new Thread(new Runnable() {
@Override
public void run() {
while (progress <= 100) {
progress += 2;
progressBar.setProgress(progress);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
});
}