代码之家  ›  专栏  ›  技术社区  ›  Peterdk

安卓:如何获得一个自定义视图来部分重绘?

  •  14
  • Peterdk  · 技术社区  · 16 年前

    我有一个自定义视图,它填充了整个屏幕。(钢琴键盘) 当用户触摸键时,它会导致 invalidate() 被调用,整个键盘被重新绘制,用触摸键显示新的状态。

    目前的视图非常简单,但我计划添加一点更好的图形。由于整个键盘是动态渲染的,这将使重新绘制整个键盘更加昂贵。

    所以我想,让我们来研究部分重绘。现在我打电话 invalidate(Rect dirty) 有正确的脏区。我设定我的 onDraw(Canvas canvas) 方法只在脏区域中绘制键,如果我确实需要部分重绘。这会导致这些键被绘制,但键盘的其余部分完全是黑色的/根本没有绘制。

    我不该等那个电话吗 失效(rect脏) 将“缓存”当前 canvas 只有“允许”在脏区绘图?

    我有什么方法可以实现我想要的吗?(一种“缓存”画布并只重新绘制脏区域的方法吗?)

    2 回复  |  直到 10 年前
        1
  •  19
  •   Peterdk    15 年前

    目前最好的解决方法是手动将整个画布缓存到位图中:

     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 每一次,但这都是细节。

    另请注意:位图对应用程序的内存使用非常重要。我缓存了一个与滚动条一起使用的视图,它的高度是设备高度的5倍,因为它使用了10MB的内存!

        2
  •  5
  •   MappaM    15 年前

    为了补充彼得克的回答,您可以将操作保存在图片中而不是位图中。

    • 位图将保存所有像素,如 他说可能需要很多 记忆。
    • 图片将保存 呼叫,如drawrect、drawline等。

    这取决于应用程序中真正重要的内容:大量的绘图操作、一些绘图操作,但由大量计算控制、大量空白/未使用的空间(首选图片)等。