package com.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 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 final int TEXT_COLOR = Color.parseColor("#9B9A9B"); private final int GRAY_COLOR = Color.parseColor("#D4D3D4"); //40 perche su 7 giorni fa 280, in teoria rosso pieno private final int RED_COLOR = Color.argb(40, 255, 0, 51); 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 = ChartUtils.sp2px(context, 15); lineThickness = ChartUtils.dip2px(context, 1); lineLength = ChartUtils.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; } }