项目中有一个统计信息的饼状图:
看到这种图首先想到了MPAndroidChart开源图库. 具体参考
http://blog.csdn.net/shineflowers/article/details/44701645
http://www.tuicool.com/articles/NviA3iU
但是导入的jar包是几百KB,具体记不大清楚了. 又查了下发现了hellochart,但是jar包依然需要200多KB,
刚开始以为自己直接写不太好写,但是后来发现,可以直接调用方法画空心圆和弧形.具体参考http://book.51cto.com/art/201204/328247.htm
在以前写的进度条的代码中用可这个具体参考: http://blog.csdn.net/xiaanming/article/details/10298163
结合这些资源,自己写了下: 在上面的这个链接中用到了自定义属性,并且圆弧中间有可以有文字.
直接上自己的最简化的代码:
/**
* 百分比饼状图
*
*/
public class PieCharView extends View {
/**
* 画笔对象的引用
*/
private Paint paint;
/**
* 圆环的宽度
*/
private float roundWidth;
/**
* 最大进度
*/
private int max = 100;
public static final ArrayList<Integer> colors = new ArrayList() {
{
add(R.color.pie_char_1);
add(R.color.pie_char_2);
add(R.color.pie_char_3);
add(R.color.pie_char_4);
add(R.color.pie_char_5);
add(R.color.pie_char_6);
add(R.color.pie_char_7);
add(R.color.pie_char_8);
add(R.color.pie_char_9);
add(R.color.pie_char_10);
}
};
private ArrayList<Double> progresses;
public PieCharView(Context context) {
this(context, null);
}
public PieCharView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PieCharView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
paint = new Paint();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (progresses == null || progresses.size() == 0) return;
/**
* 画最外层的大圆环
*/
int centre = getWidth()/2; //获取圆心的x坐标
int radius = (int) (centre - roundWidth/2); //圆环的半径
paint.setStyle(Paint.Style.STROKE); //设置空心
paint.setStrokeWidth(roundWidth); //设置圆环的宽度
paint.setColor(getResources().getColor(R.color.pie_char_10));
paint.setAntiAlias(true); //消除锯齿
canvas.drawCircle(centre, centre, radius, paint); //画出圆环
/**
* 画圆弧 ,画圆环的进度
*/
//设置进度是实心还是空心
paint.setStrokeWidth(roundWidth); //设置圆环的宽度
RectF oval = new RectF(centre - radius, centre - radius, centre
+ radius, centre + radius); //用于定义的圆弧的形状和大小的界限
double temp = 0;
paint.setStyle(Paint.Style.STROKE);
for (int i = 0; i < progresses.size(); i++) {
if (i > colors.size() - 1) {
paint.setColor(getResources().getColor(colors.get(9)));
} else {
paint.setColor(getResources().getColor(colors.get(i)));
}
double progress = 360 * progresses.get(i) / max;
if (temp + progress > 360) {
progress = 360 - temp;
}
if (progress <= 0) break;
// -1和+1 是解决两个圆弧之间的空隙问题
canvas.drawArc(oval, (float)(-90 + temp - 1), (float)(progress + 1), false, paint); //根据进度画圆弧
temp = temp + 360 * progresses.get(i) / max;
}
}
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;
}
public void setProgress(ArrayList<Double> progresses) {
this.progresses = progresses;
postInvalidate();
}
public void setRoundWidth(float roundWidth) {
this.roundWidth = roundWidth;
}
}
调用 : 记得 dp 转成 px
mPieChar.setProgress(pges);
mPieChar.setRoundWidth(Util.dip2px(getContext(), 50));