【问题标题】:Android: How to get a custom view to redraw partially?Android:如何让自定义视图部分重绘?
【发布时间】:2023-03-19 05:10:01
【问题描述】:

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

目前视图非常简单,但我计划添加更多漂亮的图形。由于整个键盘是动态渲染的,因此重绘整个键盘的成本会更高。

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

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

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

【问题讨论】:

    标签: android drawing partial invalidation


    【解决方案1】:

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

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

    【讨论】:

    • 嗯,我不喜欢这个解决方案,因为他的键被部分绘制的原因是因为他应该首先完整地绘制他的画布。因此,问题是为什么他的画布一开始就没有正确绘制。
    • 我需要注意的是,我现在明白,当你用脏的rect 调用invalidate 时,你可以只使用正常的绘图代码,它应该只执行实际的绘图操作在肮脏的rectCanvas 丢弃rect 之外的操作。尽管如此,这意味着您自己的许多代码仍在渲染,并且在我的硬件加速测试中,它比完全渲染视图要慢。
    • 请注意,要在画布上绘制位图,绘制参数可以为空,例如canvas.drawBitmap(bitmap, 0, 0, null).
    【解决方案2】:

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

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

    这取决于您的应用程序中真正繁重的内容:大量绘制操作、少数绘制操作但受繁重计算控制、大量空白/未使用空间(首选图片)等...

    【讨论】:

    • 对不起。 Picture 会记录drawBitmap(bitmap) 的通话吗?应该不会吧?
    • 请注意,仅在软件画布上支持图片播放,因此您不能将硬件层用于使用此功能的视图。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-30
    • 2018-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多