效果图

文章开头先放上效果图。
效果图中上面的阴影图是之前的文章
Path曲线下的阴影绘制
效果图中这个平滑曲线的效果是我比较早之前项目中的一个需求,MPchart在这种需求下不仅不合适,反而还比较复杂,所以完全自定义了一个View。
实现思路
结构还是很清晰的。可以分成三个部分
mPath.reset();
mPath.moveTo(point.x, point.y);
float preX = point.x;
float preY = point.y;
for (int i = 1; i < size; i++) {
point = mPointList.get(i);
float controlX = (preX + point.x) / 2;
mPath.cubicTo(controlX, preY, controlX, point.y, point.x, point.y);
preX = point.x;
preY = point.y;
}
- 数字
数字有 X轴上的时间显示、Y轴的最大值和最小值 以及最后一个点的圆圈和文字显示
public void drawXAxis(Canvas canvas) {
float baseY = getHeight();
Paint.FontMetrics metrics = mTextPaint.getFontMetrics();
float top = baseY - metrics.bottom;
canvas.drawText(mPathValue.startTime, mXaxisPaddingLeft, top, mTextPaint);
canvas.drawText(mPathValue.endTime, mLastPoint.x - mTextPaint.measureText(mPathValue.endTime) / 2, top, mTextPaint);
}
public void drawYAxis(Canvas canvas) {
float baseY = getHeight() / 2 - mPathHeight / 2;
Paint.FontMetrics metrics = mTextPaint.getFontMetrics();
float top = baseY - metrics.bottom;
final int padding = 5;
canvas.drawText(String.valueOf(mMaxY), mYaxisPaddingLeft, top - padding, mTextPaint);
canvas.drawText(String.valueOf(mMinY), mYaxisPaddingLeft, top + mPathHeight - metrics.top + padding, mTextPaint);
}
private void drawEnd(Canvas canvas) {
drawEndString(canvas);
drawEndPointCycle(canvas);
drawQualityCycle(canvas);
}
- 数值和坐标像素的转化
这里需要注意的是整个Path曲线图在View中是居中显示,而不是从顶部开始显示
因为需要满足需求,如果所有的点在一条直线上的话,需要居中。主要计算方法如下:
float disQuality = maxY - minY;
final int startY = getHeight() / 2 - mPathHeight / 2;
float disPixel = mPathHeight;
float x;
float y;
float scale;
if (disQuality == 0) {
for (int i = 0; i < size; i++) {
x = mPathPaddingLeft + (pecX * i);
y = (startY + disPixel * 0.5f);
points.add(new Point(x, y));
}
} else {
for (int i = 0; i < size; i++) {
x = mPathPaddingLeft + (pecX * i);
scale = (maxY - list.get(i)) / disQuality;
y = (startY + disPixel * scale);
points.add(new Point(x, y));
}
}
代码地址
具体代码见Demo:https://github.com/xindasunday/ShareDemo |