1.效果图
2.代码
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.view.View; /** * 使用说明 <br/> * 1.XML定义<br/> * <com.longyuan.sdkdemo.CirclePieView <br/> * android:id="@+id/cpv" <br/> * android:layout_width="100dp" <br/> * android:layout_height="100dp" <br/> * android:layout_marginLeft="10dp" <br/> * android:layout_marginTop="10dp" > <br/> * </com.longyuan.sdkdemo.CirclePieView> <br/> * 2.设置比分<br/> * CirclePieView.setScore(4, 3, true, 1);<br/> * @author niexiaoqiang */ public class CirclePieView extends View { public int animationType = 1; public static final int E_C = 10; private int mWidth = 0; private int mHeight = 0; private int leftColor = Color.rgb(255, 255, 0); private int rightColor = Color.rgb(255, 0, 255); private int textBgColor = Color.rgb(255, 255, 255); private int bgColor = Color.rgb(0, 0, 0); //不能大于99 private int leftScore = 0; //不能大于99 private int rightScore = 0; private Paint textPaint; private Paint leftPaint; private Paint rightPaint; private Paint textBgPaint; private Paint bgPaint; private RectF drawRect = new RectF(); private int circleWidth = 10; private int leftCircle = 180; private int rightCircle = 180; private int currentC = 360; //是否已经设置比分如果没有设置,则不绘制文字以及圆环 private boolean initedScrore = false; private boolean stopped = true; private void init(Context context) { textPaint = new Paint(); textPaint.setAntiAlias(true); textPaint.setColor(Color.BLACK); textPaint.setFakeBoldText(true); leftPaint = new Paint(); leftPaint.setAntiAlias(true); leftPaint.setColor(leftColor); rightPaint = new Paint(); rightPaint.setAntiAlias(true); rightPaint.setColor(rightColor); textBgPaint = new Paint(); textBgPaint.setAntiAlias(true); textBgPaint.setColor(textBgColor); bgPaint = new Paint(); bgPaint.setAntiAlias(true); bgPaint.setColor(bgColor); circleWidth = dip2px(context, 10); } public static int dip2px(Context context, float dipValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dipValue * scale + 0.5f); } /** * 如果inited==false将不绘制比分,以及圆环 * @param initedScrore */ public void setInitedScrore(boolean initedScrore) { this.initedScrore = initedScrore; this.invalidate(); } /** * 调用该方法设置比分 * @param leftScore 左边的比分 * @param rightScore 右边的比分 * @param needAnimation 是否需要动画 * @param animationType 0: 旋转,1:展开 */ public void setScore(int leftScore, int rightScore, boolean needAnimation, int animationType) { this.leftScore = leftScore; this.rightScore = rightScore; this.animationType = animationType; //计算占比 if (leftScore == 0 && rightScore == 0) { leftCircle = 180; } else { leftCircle = (int) (((float) leftScore / (float) (leftScore + rightScore)) * (float) 360); leftCircle = leftCircle % 2 == 0 ? leftCircle : leftCircle - 1; } rightCircle = 360 - leftCircle; if (needAnimation) { currentC = 0; stopped = false; } setInitedScrore(true); } @Override public void onDraw(Canvas canvas) { super.onDraw(canvas); //背景 canvas.drawCircle(mWidth / 2, mHeight / 2, (mWidth - 2) / 2, bgPaint); if (initedScrore) { //画圆 drawRect.set(0, 0, mWidth, mHeight); int currentRightCircle = rightCircle * currentC / 360; if (animationType == 0) { canvas.drawArc(drawRect, 180 - leftCircle / 2, currentC, true, leftPaint); if (360 - currentC <= currentRightCircle) { canvas.drawArc(drawRect, 0 - rightCircle / 2, currentRightCircle, true, rightPaint); } } else { //画左边时以180°为中心,上下分别进行一次 canvas.drawArc(drawRect, 180, leftCircle / 2 * currentC / 360, true, leftPaint); canvas.drawArc(drawRect, 180, -leftCircle / 2 * currentC / 360, true, leftPaint); //画右边时候以0°为中心,上下分别进行一次 canvas.drawArc(drawRect, 0, rightCircle / 2 * currentC / 360, true, rightPaint); canvas.drawArc(drawRect, 0, -rightCircle / 2 * currentC / 360, true, rightPaint); } } //绘制文字背景 canvas.drawCircle(mWidth / 2, mHeight / 2, (mWidth - circleWidth * 2) / 2, textBgPaint); if (initedScrore) { drawText(canvas); } currentC += E_C; if (currentC < 360) { postInvalidate(); return; } if (currentC > 360) { currentC = 360; } if (!stopped) { postInvalidate(); stopped = true; } } /** * 画出文字 * @param canvas */ private void drawText(Canvas canvas) { /////////////最后画出文字////////////// int allTextWidth = mWidth - circleWidth * 2; textPaint.setTextSize(allTextWidth / 4 * currentC / 360); FontMetrics fontMetrics = textPaint.getFontMetrics(); float textBaseLine = mHeight / 2 - ((fontMetrics.top - fontMetrics.bottom) / 2 + fontMetrics.bottom); //冒号 String mindleString = ":"; float mindleTextWidth = textPaint.measureText(mindleString); float midleTextleft = (allTextWidth - mindleTextWidth) / 2 + circleWidth; canvas.drawText(mindleString, midleTextleft, textBaseLine, textPaint); //标线 // canvas.drawLine(midleTextleft, 0, midleTextleft, mHeight, rightPaint); // canvas.drawLine(midleTextleft + mindleTextWidth, 0, midleTextleft + mindleTextWidth, mHeight, rightPaint); //左边文字 String leftString = getLeftString(); float leftTextWidth = textPaint.measureText(leftString); float leftTextLeft = (midleTextleft - leftTextWidth) / 2 + circleWidth / 2; canvas.drawText(leftString, leftTextLeft, textBaseLine, textPaint); //标线 // canvas.drawLine(leftTextLeft, 0, leftTextLeft, mHeight, rightPaint); // canvas.drawLine(leftTextLeft + leftTextWidth, 0, leftTextLeft + leftTextWidth, mHeight, rightPaint); //右边的文字 String rightString = getRightString(); float rightTextWidth = textPaint.measureText(rightString); float rightTextLeft = (midleTextleft + mindleTextWidth) + (allTextWidth - (midleTextleft + mindleTextWidth) - rightTextWidth) / 2 + circleWidth / 2; canvas.drawText(rightString, rightTextLeft, textBaseLine, textPaint); //标线 // canvas.drawLine(rightTextLeft, 0, rightTextLeft, mHeight, rightPaint); // canvas.drawLine(rightTextLeft + rightTextWidth, 0, rightTextLeft + rightTextWidth, mHeight, rightPaint); } private String getLeftString() { if (leftScore < 10) { return "0" + leftScore; } return leftScore + ""; } private String getRightString() { if (rightScore < 10) { return "0" + rightScore; } return rightScore + ""; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mHeight = getMeasuredHeight(); mWidth = getMeasuredWidth(); } public CirclePieView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.init(context); } public CirclePieView(Context context, AttributeSet attrs) { super(context, attrs); this.init(context); } public CirclePieView(Context context) { super(context); this.init(context); } }