源码如下:
package com.zlzxm.popue;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
public class CakeViewextends View{
private int mWidth =0;
private int mHeight =0;
private PaintmPaint =new Paint(Paint.ANTI_ALIAS_FLAG);
private String[]mItemNames =null;
private int[]mColors =null;
private int[]mValues =null;
private int mCircleCenterX;
private int mCircleCenterY;
private RectFmCircleRect;
private float mTextWidth =0;
private float mTextHeight =0;
private PaintmTextPaint =new Paint(Paint.ANTI_ALIAS_FLAG);
private int mCircleR =0;
private PaintmCirclePaint =new Paint(Paint.ANTI_ALIAS_FLAG);
private int mTextBaseLine =0;
//属性
private int mTextSpaceRight =50;
private int mTextSpace =50;
private int mTextSize =50;
private int mCircleTextSpace =50;
private int mInitCircleColor = Color.RED;
private int mCircleSpac =0;
public CakeView(Context context) {
super(context);
}
public CakeView(Context context,@Nullable AttributeSet attrs) {
super(context, attrs);
}
public CakeView(Context context,@Nullable AttributeSet attrs,int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public CakeView initItem(String[] itemNames,int[] colors){
if(itemNames.length != colors.length){
throw new RuntimeException(" please check itemsCounts ");
}
mItemNames = itemNames;
mColors = colors;
return this;
}
public void setValue(int[] values){
mValues = values;
postInvalidate();
}
public CakeView setTextSpaceRight(int mTextSpaceRight) {
this.mTextSpaceRight = mTextSpaceRight;
return this;
}
public CakeView setTextSize(int mTextSize) {
this.mTextSize = mTextSize;
return this;
}
public CakeView setTextSpace(int mTextSpace) {
this.mTextSpace = mTextSpace;
return this;
}
public CakeView setmCircleTextSpace(int mCircleTextSpace) {
this.mCircleTextSpace = mCircleTextSpace;
return this;
}
public CakeView setInitCircleColor(int mInitCircleColor) {
this.mInitCircleColor = mInitCircleColor;
return this;
}
public CakeView setCircleSpac(int mCircleSpac) {
this.mCircleSpac = mCircleSpac;
return this;
}
@Override
protected void onSizeChanged(int w,int h,int oldw,int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w;
mHeight = h;
int circleR = Math.min(w,h) /4;
mCircleCenterX = circleR;
mCircleCenterY = h /2;
mCircleRect =new RectF();
mCircleRect.left =0 +mCircleSpac;
mCircleRect.top =mCircleCenterY - circleR;
mCircleRect.right = circleR *2 +mCircleSpac;
mCircleRect.bottom =mCircleCenterY + circleR;
mPaint.setStrokeWidth(5);
mPaint.setStyle(Paint.Style.FILL.FILL);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setColor(Color.WHITE);
mTextPaint.setColor(Color.BLACK);
mTextPaint.setTextSize(mTextSize);
mTextPaint.setTextAlign(Paint.Align.LEFT);
mTextPaint.setStyle(Paint.Style.FILL);
mTextPaint.setStrokeWidth(5);
for (int i =0; i
Rect rect =new Rect();
mTextPaint.getTextBounds(mItemNames[i],0,mItemNames[i].length(), rect);
if(mTextWidth < rect.width()){
mTextWidth = rect.width();
}
}
Paint.FontMetrics metrics =mTextPaint.getFontMetrics();
float top = metrics.top;
float bottom = metrics.bottom;
mTextHeight = bottom - top;
mCircleR = (int) (mTextHeight/2);
}
@Override
protected void onDraw(Canvas canvas) {
for (int i =0; i
Rect rect =new Rect(0,i* (int)mTextHeight ,2,i* (int)mTextHeight+ (int)mTextHeight);
Paint.FontMetrics metrics =mTextPaint.getFontMetrics();
float top = metrics.top;
float bottom = metrics.bottom;
mTextBaseLine = (int) ((rect.bottom + rect.top - bottom - top) /2) +mTextSpace *(i+1);//基线中间点的y轴计算公式
canvas.drawText(mItemNames[i],mWidth -mTextWidth -mTextSpaceRight,mTextBaseLine,mTextPaint);
mCirclePaint.setColor(mColors[i]);
canvas.drawCircle(mWidth -mTextWidth -mTextSpaceRight -mCircleTextSpace,(mTextSpace +mTextHeight) * (i+1) -mCircleR ,mCircleR,mCirclePaint);
}
if(mValues ==null){
mPaint.setColor(mInitCircleColor);
canvas.drawArc(mCircleRect, -90 ,360,true,mPaint);
return;
}
float[] precent = caculate(mValues);
int rotateNow =0;
for (int i =0; i < precent.length ; i++) {
mPaint.setColor(mColors[i]);
canvas.drawArc(mCircleRect,90 + rotateNow, precent[i],true,mPaint);
rotateNow += precent[i];
}
}
private float[] caculate(int[] values){
float[] percent =new float[values.length];
float toatal =0f;
for (int i =0; i < values.length ; i++) {
toatal += values[i];
}
for (int i =0; i < values.length ; i++) {
percent[i] = (values[i] / toatal) *360;
}
return percent;
}
}
使用如下:
cakeView = findViewById(R.id.cake);
cakeView.initItem(new String[]{"有效单号","低可能性单号","高可能性单号"},new int[]{Color.RED,Color.GRAY,Color.BLACK})
.setTextSize(dptopx(17))
.setCircleSpac(dptopx(20));
cakeView.setValue(new int[]{100,200,300});
ps:没有动态加载效果,等待完善和优化