Android:如何获取部分重绘的自定义视图?

Pet*_*rdk 14 android drawing partial invalidation

我有一个自定义视图,填满了我的整个屏幕.(钢琴键盘)当用户触摸该键时,它将invalidate()被调用并且整个键盘被重新绘制以用触摸的键显示新状态.

目前视图非常简单,但我计划添加更多漂亮的图形.由于整个键盘是动态渲染的,这将使重绘整个键盘更加昂贵.

所以我想,让我们看看部分重绘.现在我打电话invalidate(Rect dirty)给正确的脏区.onDraw(Canvas canvas)如果我确实想要部分重绘,我将我的方法设置为仅在脏区域中绘制键.这会导致绘制这些键,但键盘的其余部分完全是黑色/根本不绘制.

我错误地期望调用invalidate(Rect dirty)会"缓存"当前canvas,并且只允许在脏区域中"绘制"绘图吗?

有什么方法可以实现我想要的吗?(一种"缓存"画布并仅重绘脏区的方法?"

Pet*_*rdk 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);
     }
 }
Run Code Online (Sandbox Code Playgroud)

当然,你需要存储关于自己重绘的信息,最好不要Paint每次都使用新的,但这是细节.

另请注意:位图对应用程序的内存使用量非常重.当我缓存一个与滚动器一起使用的View时,我崩溃了,这个设置高度是设备高度的5倍,因为它使用了大于10MB的内存!


Map*_*paM 5

为了补充Peterdk的答案,您可以将操作保存在图片而不是位图中.

  • 一个位图将保存所有像素,就像他说它可能需要大量内存.
  • 图片将保存调用,如drawRect,drawLine等.

这取决于您的应用中真正重要的东西:大量的绘制操作,一些绘制操作,但由大量计算控制,大量空白/未使用空间(更喜欢图片)等...