188 lines
7.1 KiB
Java
188 lines
7.1 KiB
Java
package im.dacer.androidcharts;
|
|
|
|
import android.content.Context;
|
|
import android.graphics.Canvas;
|
|
import android.graphics.Color;
|
|
import android.graphics.Paint;
|
|
import android.graphics.Point;
|
|
import android.graphics.Rect;
|
|
import android.graphics.RectF;
|
|
import android.util.AttributeSet;
|
|
import android.view.View;
|
|
import java.util.ArrayList;
|
|
|
|
/**
|
|
* Created by Dacer on 11/13/13.
|
|
*/
|
|
public class ClockPieView extends View {
|
|
|
|
private final int TEXT_COLOR = Color.parseColor("#9B9A9B");
|
|
private final int GRAY_COLOR = Color.parseColor("#D4D3D4");
|
|
private final int RED_COLOR = Color.argb(50, 255, 0, 51);
|
|
private Paint textPaint;
|
|
private Paint redPaint;
|
|
private Paint linePaint;
|
|
private Paint whitePaint;
|
|
private int mViewWidth;
|
|
private int mViewHeight;
|
|
private int textSize;
|
|
private int pieRadius;
|
|
private Point pieCenterPoint;
|
|
private Point tempPoint;
|
|
private Point tempPointRight;
|
|
private int lineLength;
|
|
private float leftTextWidth;
|
|
private float rightTextWidth;
|
|
private float topTextHeight;
|
|
private int lineThickness;
|
|
private RectF cirRect;
|
|
private Rect textRect;
|
|
private ArrayList<ClockPieHelper> pieArrayList = new ArrayList<ClockPieHelper>();
|
|
private Runnable animator = new Runnable() {
|
|
@Override public void run() {
|
|
boolean needNewFrame = false;
|
|
for (ClockPieHelper pie : pieArrayList) {
|
|
pie.update();
|
|
if (!pie.isAtRest()) {
|
|
needNewFrame = true;
|
|
}
|
|
}
|
|
if (needNewFrame) {
|
|
postDelayed(this, 10);
|
|
}
|
|
invalidate();
|
|
}
|
|
};
|
|
|
|
public ClockPieView(Context context) {
|
|
this(context, null);
|
|
}
|
|
|
|
public ClockPieView(Context context, AttributeSet attrs) {
|
|
super(context, attrs);
|
|
textSize = MyUtils.sp2px(context, 15);
|
|
lineThickness = MyUtils.dip2px(context, 1);
|
|
lineLength = MyUtils.dip2px(context, 10);
|
|
|
|
textPaint = new Paint();
|
|
textPaint.setAntiAlias(true);
|
|
textPaint.setColor(TEXT_COLOR);
|
|
textPaint.setTextSize(textSize);
|
|
textPaint.setTextAlign(Paint.Align.CENTER);
|
|
Paint.FontMetrics fm = new Paint.FontMetrics();
|
|
textPaint.getFontMetrics(fm);
|
|
textRect = new Rect();
|
|
textPaint.getTextBounds("18", 0, 1, textRect);
|
|
redPaint = new Paint(textPaint);
|
|
redPaint.setColor(RED_COLOR);
|
|
linePaint = new Paint(textPaint);
|
|
linePaint.setColor(GRAY_COLOR);
|
|
linePaint.setStrokeWidth(lineThickness);
|
|
whitePaint = new Paint(linePaint);
|
|
whitePaint.setColor(Color.WHITE);
|
|
tempPoint = new Point();
|
|
pieCenterPoint = new Point();
|
|
tempPointRight = new Point();
|
|
cirRect = new RectF();
|
|
leftTextWidth = textPaint.measureText("18");
|
|
rightTextWidth = textPaint.measureText("6");
|
|
topTextHeight = textRect.height();
|
|
}
|
|
|
|
public void setDate(ArrayList<ClockPieHelper> helperList) {
|
|
if (helperList != null && !helperList.isEmpty()) {
|
|
int pieSize = pieArrayList.isEmpty() ? 0 : pieArrayList.size();
|
|
for (int i = 0; i < helperList.size(); i++) {
|
|
if (i > pieSize - 1) {
|
|
// float mStart = helperList.get(i).getStart();
|
|
pieArrayList.add(new ClockPieHelper(0, 0, helperList.get(i)));
|
|
} else {
|
|
pieArrayList.set(i, pieArrayList.get(i).setTarget(helperList.get(i)));
|
|
}
|
|
}
|
|
int temp = pieArrayList.size() - helperList.size();
|
|
for (int i = 0; i < temp; i++) {
|
|
pieArrayList.remove(pieArrayList.size() - 1);
|
|
}
|
|
} else {
|
|
pieArrayList.clear();
|
|
}
|
|
|
|
removeCallbacks(animator);
|
|
post(animator);
|
|
}
|
|
|
|
@Override protected void onDraw(Canvas canvas) {
|
|
drawBackground(canvas);
|
|
if (pieArrayList != null) {
|
|
for (ClockPieHelper helper : pieArrayList) {
|
|
canvas.drawArc(cirRect, helper.getStart(), helper.getSweep(), true, redPaint);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void drawBackground(Canvas canvas) {
|
|
for (int i = 0; i < 12; i++) {
|
|
tempPoint.set(pieCenterPoint.x - (int) (Math.sin(Math.PI / 12 * i) * (pieRadius
|
|
+ lineLength)), pieCenterPoint.y - (int) (Math.cos(Math.PI / 12 * i) * (
|
|
pieRadius
|
|
+ lineLength)));
|
|
tempPointRight.set(pieCenterPoint.x + (int) (Math.sin(Math.PI / 12 * i) * (pieRadius
|
|
+ lineLength)), pieCenterPoint.y + (int) (Math.cos(Math.PI / 12 * i) * (
|
|
pieRadius
|
|
+ lineLength)));
|
|
canvas.drawLine(tempPoint.x, tempPoint.y, tempPointRight.x, tempPointRight.y,
|
|
linePaint);
|
|
}
|
|
canvas.drawCircle(pieCenterPoint.x, pieCenterPoint.y, pieRadius + lineLength / 2,
|
|
whitePaint);
|
|
canvas.drawCircle(pieCenterPoint.x, pieCenterPoint.y, pieRadius + lineThickness, linePaint);
|
|
canvas.drawCircle(pieCenterPoint.x, pieCenterPoint.y, pieRadius, whitePaint);
|
|
canvas.drawText("0", pieCenterPoint.x, topTextHeight, textPaint);
|
|
canvas.drawText("12", pieCenterPoint.x, mViewHeight, textPaint);
|
|
canvas.drawText("18", leftTextWidth / 2, pieCenterPoint.y + textRect.height() / 2,
|
|
textPaint);
|
|
canvas.drawText("6", mViewWidth - rightTextWidth / 2,
|
|
pieCenterPoint.y + textRect.height() / 2, textPaint);
|
|
}
|
|
|
|
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
mViewWidth = measureWidth(widthMeasureSpec);
|
|
mViewHeight = measureHeight(heightMeasureSpec);
|
|
pieRadius = mViewWidth / 2 - lineLength * 2 - (int) (textPaint.measureText("18") / 2);
|
|
pieCenterPoint.set(mViewWidth / 2 - (int) rightTextWidth / 2 + (int) leftTextWidth / 2,
|
|
mViewHeight / 2 + textSize / 2 - (int) (textPaint.measureText("18") / 2));
|
|
cirRect.set(pieCenterPoint.x - pieRadius, pieCenterPoint.y - pieRadius,
|
|
pieCenterPoint.x + pieRadius, pieCenterPoint.y + pieRadius);
|
|
setMeasuredDimension(mViewWidth, mViewHeight);
|
|
}
|
|
|
|
private int measureWidth(int measureSpec) {
|
|
int preferred = 3;
|
|
return getMeasurement(measureSpec, preferred);
|
|
}
|
|
|
|
private int measureHeight(int measureSpec) {
|
|
int preferred = mViewWidth;
|
|
return getMeasurement(measureSpec, preferred);
|
|
}
|
|
|
|
private int getMeasurement(int measureSpec, int preferred) {
|
|
int specSize = View.MeasureSpec.getSize(measureSpec);
|
|
int measurement;
|
|
|
|
switch (View.MeasureSpec.getMode(measureSpec)) {
|
|
case View.MeasureSpec.EXACTLY:
|
|
measurement = specSize;
|
|
break;
|
|
case View.MeasureSpec.AT_MOST:
|
|
measurement = Math.min(preferred, specSize);
|
|
break;
|
|
default:
|
|
measurement = preferred;
|
|
break;
|
|
}
|
|
return measurement;
|
|
}
|
|
}
|