我有一个填充整个屏幕的自定义视图。 (钢琴键盘)
当用户触摸该键时,会调用invalidate()
并重新绘制整个键盘以显示带有触摸键的新状态。
目前视图非常简单,但我计划添加更多漂亮的图形。由于整个键盘是动态渲染的,这将使重绘整个键盘更加昂贵。
所以我想,让我们看看部分重绘。现在我用正确的脏区域调用invalidate(Rect dirty)
。如果我确实想要部分重绘,我将onDraw(Canvas canvas)
方法设置为仅绘制脏区域中的键。这会导致绘制这些键,但键盘的其余部分完全是黑色/根本不绘制。
我错误地期望调用invalidate(Rect dirty)
会“缓存”当前canvas
,并且只允许“允许”在脏区域中绘图?
有什么方法可以达到我的目的吗? (一种“缓存”画布并仅重绘脏区的方法?“
答案 0 :(得分:19)
目前很好的解决方法是手动将完整画布缓存到位图:
private void onDraw(Canvas canvas)
{
if (!initialDrawingIsPerformed)
{
this.cachedBitmap = Bitmap.createBitmap(getWidth(), getHeight(),
Config.ARGB_8888); //Change to lower bitmap config if possible.
Canvas cacheCanvas = new Canvas(this.cachedBitmap);
doInitialDrawing(cacheCanvas);
canvas.drawBitmap(this.cachedBitmap, 0, 0, new Paint());
initialDrawingIsPerformed = true;
}
else
{
canvas.drawBitmap(this.cachedBitmap, 0, 0, new Paint());
doPartialRedraws(canvas);
}
}
当然,您需要存储有关自己重绘内容的信息,最好不要每次都使用新的Paint
,但这是详细信息。
另请注意:位图对应用的内存使用量非常重。当我缓存了一个与滚动条一起使用的View时,我崩溃了,这就像设备高度的5倍,因为它使用了> 10MB内存!
答案 1 :(得分:5)
为了补充Peterdk的答案,您可以将操作保存在图片而不是位图中。
这取决于您的应用程序中真正重要的东西:大量的绘制操作,一些绘制操作,但是通过大量计算控制,大量空白/未使用空间(更喜欢图片)等...