Skip to content

Instantly share code, notes, and snippets.

@spiritedRunning
Last active August 18, 2016 03:23
Show Gist options
  • Save spiritedRunning/b14ed8dcbc3bc92fa1abefe702017953 to your computer and use it in GitHub Desktop.
Save spiritedRunning/b14ed8dcbc3bc92fa1abefe702017953 to your computer and use it in GitHub Desktop.
Drawing Dynamic Pie View
/**
* @brief 圆环饼图统计view
* Created by zhen.liu on 1/5/16.
*/
public class PieRingView extends View {
private float convertAngel;
private float radiusCircle;
// 用于绘制圆弧的矩形
private RectF mCircleRectF;
private Paint paint;
private Paint ringPaint;
// 保持数据角度信息
private float[] dataAngel;
// 从-90度开始绘制圆弧
private int startAngle = -90;
private RingInfoHolder infoHolder, infoHolder1, infoHolder2;
// 存储饼图信息
private List<RingInfoHolder> ringInfoHolderList = new ArrayList<>();
public PieRingView(Context context) {
this(context, null);
}
public PieRingView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PieRingView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//获取自定义属性:圆弧半径
TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.ringCircleView);
radiusCircle = mTypedArray.getDimension(R.styleable.ringCircleView_ringPieRadius, DeviceUtil.dip2px(context, 40));
mTypedArray.recycle();
mCircleRectF = new RectF();
//初始化画笔
initPaint();
}
@Override
protected void onDraw(Canvas canvas) {
if (ringInfoHolderList.size() < 3) {
return;
}
// float startAngle = 0;
// float sweepAngle = 0;
// long currentSum = 0;
// long sum = 0;
// for (RingInfoHolder ringHolder : ringInfoHolderList) {
// sum += ringHolder.value;
// }
// Log.d(TAG, "pie sum: " + sum);
//
// for (RingInfoHolder ringInfoHolder : ringInfoHolderList) {
// startAngle = (float)currentSum / sum * 360 - 90f;
// currentSum += ringInfoHolder.value;
// sweepAngle = (float)ringInfoHolder.value / sum * 360 + 1f;
//
// drawRing(canvas, ringInfoHolder.color, ringInfoHolder.radius, startAngle, sweepAngle);
// }
//初始化圆弧所在矩形范围
mCircleRectF.left = getWidth() / 2 - radiusCircle;
mCircleRectF.top = mCircleRectF.left;
mCircleRectF.right = mCircleRectF.left + 2 * radiusCircle;
mCircleRectF.bottom = mCircleRectF.top + 2 * radiusCircle;
infoHolder = ringInfoHolderList.get(0);
infoHolder1 = ringInfoHolderList.get(1);
infoHolder2 = ringInfoHolderList.get(2);
// 计算当前角度百分比
if (convertAngel <= dataAngel[0]) {
drawRing(canvas, infoHolder.color, infoHolder.stokewidth, startAngle, convertAngel);
} else if (convertAngel >= dataAngel[0] && convertAngel <= dataAngel[1]) {
drawRing(canvas, infoHolder.color, infoHolder.stokewidth, startAngle, dataAngel[0] + 1);
drawRing(canvas, infoHolder1.color, infoHolder1.stokewidth, startAngle + dataAngel[0], convertAngel - dataAngel[0] + 1);
} else if (convertAngel >= dataAngel[1]) {
drawRing(canvas, infoHolder.color, infoHolder.stokewidth, startAngle, dataAngel[0]);
drawRing(canvas, infoHolder1.color, infoHolder1.stokewidth, startAngle + dataAngel[0], dataAngel[1] + 1);
drawRing(canvas, infoHolder2.color, infoHolder2.stokewidth,
startAngle + dataAngel[0] + dataAngel[1], convertAngel - dataAngel[0] - dataAngel[1]);
}
}
/**
* 初始化画笔
*/
private void initPaint() {
paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true);
paint.setDither(true);
paint.setStrokeWidth(DeviceUtil.convertDipToPx(60));
ringPaint = new Paint(paint);
}
/**
* 设置数据源
*/
public void setData(List<RingInfoHolder> data) {
if (data != null) {
ringInfoHolderList.clear();
ringInfoHolderList.addAll(data);
}
long sumAngel = 0;
for (RingInfoHolder rih : ringInfoHolderList) {
sumAngel += rih.value;
}
// 保存圆环角度值
dataAngel = new float[ringInfoHolderList.size()];
for (int i = 0; i < ringInfoHolderList.size(); i++) {
float rate = (float) ringInfoHolderList.get(i).value / sumAngel * 360;
BigDecimal bd = new BigDecimal(rate);
dataAngel[i] = bd.setScale(1, BigDecimal.ROUND_HALF_UP).floatValue();
// 统计得到从某一角度计算起的角度总和
if (i > 0) {
dataAngel[i] += dataAngel[i - 1];
BigDecimal bdl = new BigDecimal(dataAngel[i]);
dataAngel[i] = bdl.setScale(1, BigDecimal.ROUND_HALF_UP).floatValue();
}
}
}
/**
* 开启动画
*
* @param duration 动画时长
*/
public void startAnimation(long duration) {
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 360);
valueAnimator.setDuration(duration);
valueAnimator.setInterpolator(new AccelerateInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
convertAngel = (float) animation.getAnimatedValue();
invalidate();
}
});
valueAnimator.start();
}
/**
* 绘制圆弧
*/
private void drawRing(Canvas canvas, int color, int stokewidth, float startAngle, float sweepAngle) {
ringPaint.setStrokeWidth(stokewidth);
ringPaint.setColor(color);
canvas.drawArc(mCircleRectF, startAngle, sweepAngle, false, ringPaint);
}
/**
* 圆环信息
*/
public static final class RingInfoHolder {
// 扇形数值
private long value;
// 圆环颜色
private int color;
// 厚度
private int stokewidth;
public RingInfoHolder(long value, int color, int stokewidth) {
this.value = value;
this.color = color;
this.stokewidth = stokewidth;
}
}
}
// 开始绘制饼图
List<PieRingView.RingInfoHolder> ringInfoHolders = new ArrayList<PieRingView.RingInfoHolder>();
ringInfoHolders.add(new PieRingView.RingInfoHolder(beeAppSize,
ContextCompat.getColor(context, R.color.base_yellow),
DeviceUtil.dip2px(context, 65)));
ringInfoHolders.add(new PieRingView.RingInfoHolder(otherSize,
ContextCompat.getColor(context, R.color.base_bg_chat),
DeviceUtil.dip2px(context, 60)));
ringInfoHolders.add(new PieRingView.RingInfoHolder(availableSize,
ContextCompat.getColor(context, R.color.lightgrey),
DeviceUtil.dip2px(context, 60)));
pieRingView.setData(ringInfoHolders);
pieRingView.startAnimation(1000);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment