Android:如何让自定义视图部分重绘?

发布于 2024-09-03 21:17:38 字数 483 浏览 3 评论 0原文

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

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

所以我想,让我们研究一下部分重画。现在,我使用正确的脏区域调用 invalidate(Rect dirty) 。如果我确实想要部分重绘,我将我的 onDraw(Canvas canvas) 方法设置为仅在脏区域中绘制键。这会导致这些键被绘制,但键盘的其余部分是完全黑色的/根本没有绘制。

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

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

I have a custom view that fills my entire screen. (A piano keyboard)
When a user touches the key, it causes invalidate() to be called and the whole keyboard gets redrawn to show the new state with a touched key.

Currently the view is very simple, but I plan to add a bit more nice graphics. Since the whole keyboard is dynamically rendered this would make redrawing the entire keyboard more expensive.

So I thought, let's look into partial redrawing. Now I call invalidate(Rect dirty) with the correct dirty region. I set my onDraw(Canvas canvas) method to only draw the keys in the dirty region if I do indeed want a partial redraw. This results in those keys being drawn, but the rest of the keyboard is totally black/not drawn at all.

Am I wrong in expecting that calling invalidate(Rect dirty) would "cache" the current canvas, and only "allows" drawing in the dirty region?

Is there any way I can achieve what I want? (A way to "cache" the canvas and only redraw the dirty area?"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小ぇ时光︴ 2024-09-10 21:17:38

当前不错的解决方法是将整个画布手动缓存到位图:

 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内存!

Current nice workaround is to manually cache the full canvas to a bitmap:

 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);
     }
 }

Ofcourse, you need to store the info about what to redraw yourself and preferably not use a new Paint everytime, but that are details.

Also note: Bitmaps are quite heavy on the memory usage of your app. I had crashes when I cached a View that was used with a scroller and that was like 5 times the height of the device, since it used > 10MB memory!

终陌 2024-09-10 21:17:38

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

  • 位图将保存所有像素,例如
    他说这可能需要很多时间
    记忆。
  • 图片将保存
    调用,如drawRect、drawLine等。

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

To complement Peterdk's answer, you could save your operations in a Picture instead of a Bitmap.

  • A Bitmap will save all pixels, like
    he said it could take a lot of
    memory.
  • A Picture will save the
    calls, like drawRect, drawLine, etc.

It depends of what is really heavy in your application : a lot of draw operations, a few draw operations but controlled by heavy calculations, a lot of blank/unused space (prefer Picture) etc...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文