Android自定义睡眠下表统计图,Android 进阶自定义View(5)图表统计PieChartView圆饼图的实现...

今天讲图表统计中比较常用的一个,像支付宝的月账单啥的,都是用圆饼图来做数据统计的,先看一下我最终实现的效果图:

c9a12370631d

image.png

该效果实际上是两个实心圆叠加后的效果。

c9a12370631d

image.png

c9a12370631d

image.png

《一》View实现思路分析:

(1)根据占比集合数据,计算所需绘制的角度,动态设置画笔颜色,drawArc()绘制外圆弧

(2)drawCircle()绘制内圆

(3)确定每块圆饼的小白点的位置

(4)绘制白点的沿线和占比文字

《二》具体实现:

(1)绘制不同颜色的圆饼

for (int i = 0; i < mRateList.size(); i++) {

mPaint.setStyle(Paint.Style.FILL);

mPaint.setColor(mColorList.get(i));

// Log.e("TAG", "startAngle=" + startAngle + "--sweepAngle=" + ((int) (mRateList.get(i) * (360)) - offset));

canvas.drawArc(rectF, startAngle, (int) (mRateList.get(i) * (360)) , true, mPaint);

startAngle = startAngle + (int) (mRateList.get(i) * 360);

}

(2)绘制内圆

mPaint.setColor(ContextCompat.getColor(mContext, R.color.color_081638));

canvas.drawCircle(radius + centerPointRadius + (xOffset + yOffset + textRect.width()), radius + centerPointRadius + (xOffset + yOffset + textRect.height()), radius / 1.5f, mPaint);

(3)确定每块圆饼的小白点的位置,通过每段圆饼的起始角度确定该段圆弧的中心点位置。

private void dealPoint(RectF rectF, float startAngle, float endAngle, List pointList) {

Path path = new Path();

//通过Path类画一个90度(180—270)的内切圆弧路径

path.addArc(rectF, startAngle, endAngle);

PathMeasure measure = new PathMeasure(path, false);

// Log.e("路径的测量长度:", "" + measure.getLength());

float[] coords = new float[]{0f, 0f};

//利用PathMeasure分别测量出各个点的坐标值coords

int divisor = 1;

measure.getPosTan(measure.getLength() / divisor, coords, null);

// Log.e("coords:", "x轴:" + coords[0] + " -- y轴:" + coords[1]);

float x = coords[0];

float y = coords[1];

Point point = new Point(Math.round(x), Math.round(y));

pointList.add(point);

}

(4)绘制以白点为起点的折线和占比文字。有个细节需要注意一下,绘制折线和比例文字时,每部分沿线和文字的绘制规则不一样,我是按下面的规则处理的:将圆分为四部分,每块区分显示。

c9a12370631d

image.png

//折线横向长度

private int xOffset;

//折线偏Y方向长度

private int yOffset;

private void dealRateText(Canvas canvas, Point point, int position, List pointList) {

if (position == 0) {

lastPoint = pointList.get(0);

} else {

lastPoint = pointList.get(position - 1);

}

float[] floats = new float[8];

floats[0] = point.x;

floats[1] = point.y;

//右半圆

if (point.x >= radius + centerPointRadius + (xOffset + yOffset + textRect.width())) {

mPaint.setTextAlign(Paint.Align.LEFT);

floats[6] = point.x + xOffset;

if (point.y <= radius &#

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值