使用方法
MRoundProgressBar mPB = Fid(R.id.mPb);
mPB.addProgress(10,Color.YELLOW);
mPB.addProgress(30,Color.BLUE);
mPB.addProgress(10,Color.GREEN);
mPB.addProgress(10, Color.GRAY);
// mPB.setProgressBackgroud(Color.BLACK);
1.可能实际需求不需要中间的扇形和文字 可以直接去掉 在相关中
2.一般的progress会考虑到线程安全,那个是单进度。(下文源码中注释中有类似处理的代码)
本文暂时没有贴出具体处理相关问题。只是核心如何画
<com.rex.simpleproject.view.MRoundProgressBar
android:id="@+id/mPb"
android:layout_margin="5dp"
android:layout_width="160dp"
android:layout_height="160dp"
android:layout_gravity="center_horizontal"
app:textIsDisplayable="true"
app:roundBg="@color/main"
app:max="100"
>
com.rex.simpleproject.view.MRoundProgressBar>
源码
package com.rex.simpleproject.view;
/**
* Created by rex on 2016/6/6 0006.
*/
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import com.rex.simpleproject.R;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* 可以添加多个进度的进度条
*/
public class MRoundProgressBar extends View {
private Paint paint;
private int progress;
private int lastStart;//进度起点位置
private int centre;
private int radius;
private int roundWidth;
private int roundBg;
private int max;
private List progressInfos = new ArrayList<>();
private TypedArray mTypedArray;
private boolean textIsDisplayable;
public MRoundProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mTypedArray = context.obtainStyledAttributes(attrs,
R.styleable.MRoundProgressBar);
}
public MRoundProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
mTypedArray = context.obtainStyledAttributes(attrs,
R.styleable.MRoundProgressBar);
}
public MRoundProgressBar(Context context) {
super(context);
}
private void init() {
if (mTypedArray ==null){
roundBg = Color.RED;
roundWidth = 10;
max = 100;
lastStart = -90;
textIsDisplayable = false;
}else {
roundBg = mTypedArray.getColor(R.styleable.MRoundProgressBar_roundBg, Color.RED);
roundWidth = mTypedArray.getInt(R.styleable.MRoundProgressBar_roundWidth, 10);
max = mTypedArray.getInt(R.styleable.MRoundProgressBar_max, 100);
lastStart = mTypedArray.getInt(R.styleable.MRoundProgressBar_lastStart, -90);
textIsDisplayable = mTypedArray.getBoolean(R.styleable.MRoundProgressBar_textIsDisplayable,false);
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
init();
paint = new Paint();
Log.i("rex",
" roundBg="+roundBg+
" roundWidth="+roundWidth+
" max="+max+
" lastStart="+lastStart
);
/**
* 画最外层大圆
*/
centre = getWidth() / 2;
radius = (int) (centre - roundWidth / 2);
paint.setColor(roundBg); //设置圆环的颜色
paint.setStyle(Paint.Style.STROKE); //设置空心
paint.setStrokeWidth(roundWidth); //设置圆环的宽度
paint.setAntiAlias(true); //消除锯齿
canvas.drawCircle(centre, centre, radius, paint); //画出圆环
Iterator it = progressInfos.iterator();
while (it.hasNext()) {
ProgressInfo info = it.next();
paintArc(info.progress, info.color, canvas);
Log.i("rex", "come in onDraw");
}
/**
* 画总进度扇形
*/
paint.setStrokeWidth(0); //设置圆环的宽度
paint.setColor(Color.parseColor("#FFC0CB")); //设置进度的颜色
radius = radius - roundWidth/2;
RectF oval2 = new RectF(centre - radius, centre - radius, centre
+ radius, centre + radius); //用于定义的圆弧的形状和大小的界限
paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawArc(oval2, -90, lastStart+90, true, paint); //根据进度画扇形
/**
* 画进度百分比
*/
if (textIsDisplayable) {
String alProgress ="已使用"+(lastStart+90)*100/ 360.00f+"%";
paint.setStrokeWidth(0);
paint.setColor(roundBg);
paint.setTextSize(18);
paint.setTypeface(Typeface.DEFAULT_BOLD); //设置字体
float textWidth = paint.measureText(alProgress); //测量字体宽度,我们需要根据字体的宽度设置在圆环中间
canvas.drawText(alProgress, centre - textWidth / 2, centre + 18 / 2, paint);
}
}
/**
* 添加单个进度
* @param progress
* @param color
*/
public void addProgress(int progress, final int color) {
progressInfos.add(new ProgressInfo(progress, color));
invalidate();
}
/**
* 直接添加所有进度
* @param infos
*/
public void addProgressList(List infos) {
progressInfos.clear();
progressInfos.addAll(infos);
invalidate();
}
public void setProgressBackgroud(int color){
roundBg = color;
invalidate();
}
public void reSet() {
progressInfos.clear();
invalidate();
}
/**
* @param color
* @param progress 进度确定弧度范围
*/
private void paintArc(int progress, int color, Canvas canvas) {
Log.i("rex", "come in paintArc");
int range = 360 * progress / max;
// 画圆弧 ,画圆环的进度
//设置进度是实心还是空心
paint.setStrokeWidth(roundWidth); //设置圆环的宽度
paint.setColor(color); //设置进度的颜色
RectF oval = new RectF(centre - radius, centre - radius, centre
+ radius, centre + radius); //用于定义的圆弧的形状和大小的界限
paint.setStyle(Paint.Style.STROKE);
// //起点--距离
Log.i("rex", "lastStart=" + lastStart);
canvas.drawArc(oval, lastStart, range, false, paint); //根据进度画圆弧
lastStart = lastStart + range;
}
class ProgressInfo {
private int color;
private int progress;
@Override
public String toString() {
return "ProgressInfo{" +
"color=" + color +
", progress=" + progress +
'}';
}
public ProgressInfo(int progress, int color) {
this.color = color;
this.progress = progress;
}
}
// public synchronized int getMax() {
// return max;
// }
//
// /**
// * 设置进度的最大值
// * @param max
// */
// public synchronized void setMax(int max) {
// if(max < 0){
// throw new IllegalArgumentException("max not less than 0");
// }
// this.max = max;
// }
//
// /**
// * 获取进度.需要同步
// * @return
// */
// public synchronized int getProgress() {
// return progress;
// }
//
// /**
// * 设置进度,此为线程安全控件,由于考虑多线的问题,需要同步
// * 刷新界面调用postInvalidate()能在非UI线程刷新
// * @param progress
// */
// public synchronized void setProgress(int progress) {
// if(progress < 0){
// throw new IllegalArgumentException("progress not less than 0");
// }
// if(progress*100/360> 360-lastStart+90){
// progress = max;
// }
// if(progress <= max){
// this.progress = progress;
// postInvalidate();
// }
//
// }
}
用于自定义xml属性
<resources>
<declare-styleable name="MRoundProgressBar">
<attr name="roundBg" format="color"/>
<attr name="roundWidth" format="dimension">attr>
<attr name="max" format="integer">attr>
<attr name="textIsDisplayable" format="boolean">attr>
<attr name="lastStart" format="integer">attr>
declare-styleable>
resources>