有兴趣可以查看上传的demo。下面做了简单的说明demo中的注解很详细,有问题欢迎交流
实现功能:
1.首次进入加载动画
2.数据过多可自动折行的图例(左侧)
3.饼状图折线指向的文案说明
4.手指滑动旋转
先上了效果图实现了如上四点功能如果对你有参考意义的,可以接着听我叨叨
先前项目引入的MPAndroidChart,但只是用了一两个图就把整个库引进来有点浪费。闲来无事决定自己写一个,先来说说思路:
1.先画一个饼状图
2.实现入场的旋转动画
/**
* 差值器生成数值
*/
public void startAnima() {
final ValueAnimator mValueAnimator = ValueAnimator.ofFloat(0f, 360f);
mValueAnimator.setDuration(3 * 1000);
mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mAnimaAngle = (float) animation.getAnimatedValue();
invalidate();
}
});
mValueAnimator.start();
}
3.实现折线指向的说明
以在第一象限举例:扇形角的平分线OP 分别在N、C、M点向x轴做垂线。因为canvas.drawArc是以x轴正方向为起点即0度开始顺时针画圆(所以下边表示的角度都是顺时针表示如 角LOT:是从x轴和OT线顺时针扫过区域所成的夹角)
float a = 360 - (角LOT +角TOL / 2);
已知角a可以计算出N、M、P点的坐标。上边计算出来的都是相对于圆心O的坐标,还要转换成相对于View的坐标。
通过上边的操作可以画出折线和直线
* •--------------------------------------> canvasX +
* |
* | P Q 圆心为点 O,角用小些字母表示,点使用大写字母表示
* | •- -• 北京 N:ON为内圆半径(innerRadius)
* | ^y / M:OM为外圆半径(outRadius)
* | | / P:P点为指向说明的拐点
* | | M • C:NM的中点
* | | /|
* | | C •角平分线
* | | /| |
* | | N • | |
* | | /| | | 第一象限
* | T | / | | |
* | \ | / | | |
圆心(x,y) \|/╮ a|H|J|L
* | --------•----•-•-•--------------------->x
* | | f╰ /|﹨╯ b |
* | | / | ﹨ | 第二象限
* | | / | ﹨ | 角b = sweepAngle/2 + startAngle;
* | | / | ﹨ | 因为角B的起始点不一定是0度
* | |/ | ﹨|
* | • • D 角平分线
* | 第三象限
* |
* ∨ canvasY +
4.实现图例
实现图例主要有两个需要注意的点:
1.确定好扇形图的位置不能和图例相互遮挡
2.图例中的色块和右侧的文字需要居中对齐,这个需要计算出文本的baseline
drawText(@NonNull String text, float x, float y, @NonNull Paint paint)
x,y并不是指定文字的左上角,并且x,y与文字对齐方式有关(通过setTextAlign()指定,默认为left)
红色的Baseline是基准线,紫色的Top是文字的最顶部,也就是在drawText()中指定的x所对应,橙色的Bottom是文字的底部。
baseline对应对应值为0,在它下面的descent和bottom值为正,top和ascent为负。那文字的高度为bottom - top
Paint.FontMetrics fontMetrics=paint.getFontMetrics();
fontMetrics.top
fontMetrics.ascent
fontMetrics.descent
fontMetrics.bottom
//计算baseline
Paint.FontMetrics fontMetrics=textPaint.getFontMetrics();
float distance=(fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom;
float baseline=显示文本区域y轴中心点的坐标 + distance;