Android Canvas 下动画形状的最佳实践
Best practices for animating shapes under Android Canvas
我有一个自定义视图,它绘制了几个圆圈和大约 10 个不断更新(旋转和大小变化)的拱门。我正在尝试为整个过程制作动画,但在 Canvas 下我找不到任何好的做法(我知道基础知识 - 使用 dp 而不是 px 等等),但我不知道热正确地做动画部分。
现在我正在遍历我的所有对象,执行一些计算以确定未来的位置并绘制它们,但它看起来很不稳定。这是我目前正在做的事情:
@Override
protected void onDraw(Canvas canvas) {
for(Arch arch : arches) {
arch.update();
canvas.drawArc(arch.getRect(), -arch.getCurrentRotation(), arch.getSweepAngle(), true, paint);
}
//logo.draw(canvas);
canvas.drawCircle(width / 2, height / 2, circle_size, paint_opaque);
logo.draw(canvas);
int textX = (int) (width / 2);
int textY = (int) ((height / 2) - ((paint_text.descent() + paint_text.ascent()) / 2));
canvas.drawText(text, textX, textY, paint_text);
invalidate();
}
您的代码几乎没有错误。
您不应在自定义 Views
的 onDraw
中执行任何 繁重的 操作。这是 android 开发的一个非常重要的原则!理想情况下,您应该只在 onDraw
方法中绘制。有时你需要根据 Canvas
计算一些东西,但你应该将这类操作限制在最低限度。您可以在其他地方(不在 onDraw
中)预先分配和计算的所有内容,都应该从您的 onDraw
中提取。在你的情况下 arch.update()
(我假设计算动画的下一个 "frame" )并且你的 textX
和 textY
的计算应该移到其他地方。
invalidate()
基本上意味着您请求重绘您的 View
。当 View
被重绘时,它的 onDraw
将被调用。这就是为什么您真的不应该在 onDraw
中调用 invalidate()
!如果每个 onDraw
请求另一个 onDraw
,就会导致一种无限循环的发生。
如果您正在尝试实现帧动画,您应该在一个单独的线程中计算所有与帧相关的参数,该线程会在更新之间等待一段时间,并会调用 invalidate()
在每一个之后。
我有一个自定义视图,它绘制了几个圆圈和大约 10 个不断更新(旋转和大小变化)的拱门。我正在尝试为整个过程制作动画,但在 Canvas 下我找不到任何好的做法(我知道基础知识 - 使用 dp 而不是 px 等等),但我不知道热正确地做动画部分。
现在我正在遍历我的所有对象,执行一些计算以确定未来的位置并绘制它们,但它看起来很不稳定。这是我目前正在做的事情:
@Override
protected void onDraw(Canvas canvas) {
for(Arch arch : arches) {
arch.update();
canvas.drawArc(arch.getRect(), -arch.getCurrentRotation(), arch.getSweepAngle(), true, paint);
}
//logo.draw(canvas);
canvas.drawCircle(width / 2, height / 2, circle_size, paint_opaque);
logo.draw(canvas);
int textX = (int) (width / 2);
int textY = (int) ((height / 2) - ((paint_text.descent() + paint_text.ascent()) / 2));
canvas.drawText(text, textX, textY, paint_text);
invalidate();
}
您的代码几乎没有错误。
您不应在自定义
Views
的onDraw
中执行任何 繁重的 操作。这是 android 开发的一个非常重要的原则!理想情况下,您应该只在onDraw
方法中绘制。有时你需要根据Canvas
计算一些东西,但你应该将这类操作限制在最低限度。您可以在其他地方(不在onDraw
中)预先分配和计算的所有内容,都应该从您的onDraw
中提取。在你的情况下arch.update()
(我假设计算动画的下一个 "frame" )并且你的textX
和textY
的计算应该移到其他地方。invalidate()
基本上意味着您请求重绘您的View
。当View
被重绘时,它的onDraw
将被调用。这就是为什么您真的不应该在onDraw
中调用invalidate()
!如果每个onDraw
请求另一个onDraw
,就会导致一种无限循环的发生。如果您正在尝试实现帧动画,您应该在一个单独的线程中计算所有与帧相关的参数,该线程会在更新之间等待一段时间,并会调用
invalidate()
在每一个之后。