我正在创建一个折线图,我最初使用的代码绘制速度很慢,以至于无用。我用在网上找到的代码替换它,它变得更快。我只是好奇为什么原始代码是如此之慢。下面发布的所有代码都在自定义视图的onDraw()方法中:
原始慢代码:
float yStart = 300f;
for (int i=0; i < values.length; i++){
drawPath.moveTo(xStart, yStart);
drawPath.lineTo(xStart+10, values[i]);
drawPath.close();
canvas.drawPath(drawPath, linePaint);
xStart += 10;
yStart = values[i];
}
以后的快速代码:
float datalength = values.length;
float colwidth = (width - (2 * border)) / datalength;
float halfcol = colwidth / 2;
float lasth = 0;
for (int i = 0; i < values.length; i++) {
float val = values[i] - min;
float rat = val / diff;
float h = graphHeight * rat;
if (i > 0)
canvas.drawLine(((i - 1) * colwidth) + (horStart + 1) + halfcol, (border - lasth) + graphHeight, (i * colwidth) + (horStart + 1) + halfcol, (border - h) + graphHeight, linePaint);
lasth = h;
我只是不明白为什么一个人比另一个人效率更高。有什么想法吗?
答案 0 :(得分:2)
CLEAR
在第一部分中,对象{moveTo,lineTo,drawPath和close}有三个操作
在第二部分中,除了对象上的一个操作外,它都是浮动操作
答案 1 :(得分:1)
使用Path
s会使绘图明显慢于简单地告诉Canvas
在两点之间绘制一条直线,因为Path
是一个比drawLine()
更复杂的对象{ {1}}使用。 Path
也会根据Style
中的Paint
进行填充和框架处理,这也会导致速度放缓。
通常,在循环中使用对象并调用大量方法会降低代码的速度。
答案 2 :(得分:1)
经过一些搜索后,问题可能来自我说的地方:你应该只为图的第一个点调用moveTo,然后只在循环中调用lineTo。完全定义路径后(在for循环之后),您可以绘制它。路径已针对您的目的进行了优化,但您没有正确使用它。
http://developer.android.com/reference/android/graphics/Path.html#lineTo%28float,%20float%29
答案 3 :(得分:1)
我认为你应该这样做:
float yStart = 300f;
drawPath.moveTo(xStart, yStart);
for (int i=0; i < values.length; i++){
drawPath.lineTo(xStart+10, values[i]);
xStart += 10;
yStart = values[i];
}
drawPath.close();
canvas.drawPath(drawPath, linePaint);
否则你将在画布上画出drawPath X次的“建筑物”。
此外,您可以预先计算路径,并在onDraw中仅使用canvas.drawPath。
答案 4 :(得分:0)
此外,您应该使用path.reset()来清理内存。否则,每次使用相同的路径绘制不同的对象时,它都会绘制您在使用该路径之前绘制的所有对象。所以完整的代码就是。
float yStart = 300f;
drawPath.moveTo(xStart, yStart);
for (int i=0; i < values.length; i++){
drawPath.lineTo(xStart+10, values[i]);
xStart += 10;
yStart = values[i];
}
drawPath.close();
canvas.drawPath(drawPath, linePaint);
drawPath.reset();