`canvas.clipRect`与`Region.Op.REPLACE`的最佳替代方法是什么?

时间:2018-05-08 10:57:31

标签: android canvas

背景

我正在处理一个有很多画布而不是多个视图的库(可用here)。

问题

当我努力改进它并使其适合我们对应用程序的需求时(需要一些自定义),我注意到有些行被标记为已弃用:

canvas.clipRect(0f, mHeaderHeight + mHeaderRowPadding * 2, mHeaderColumnWidth, height.toFloat(), Region.Op.REPLACE)

事情是,我不认为有一个很好的候选人用新的API替换这行代码

我发现了什么

查看the docs,这就是以下内容:

  

此方法在API级别26中已弃用.Region.Op值为other   比INTERSECT和DIFFERENCE能够扩展剪辑。该   画布剪辑API仅用于展开剪辑   恢复操作。这使视图父级可以将画布剪切到   明确定义其子项的最大绘图区域。该   推荐的替代调用是clipRect(RectF)和   clipOutRect(RectF);

所以我尝试使用这些功能中的任何一个,但它们都引起了以前的绘制问题。

看看弃用,似乎标记了函数本身,但不是Region.Op.REPLACE:

enter image description here

所以也许它真的没有另类......

问题

  1. 在这种情况下,最好的选择是什么?
  2. 为什么要弃用它?
  3. 与某些已弃用的功能相反,我认为如果我找不到替代方案,这个功能应该是安全的,对吗?

1 个答案:

答案 0 :(得分:17)

1:现在不推荐使用自定义Region.Op的所有方法,因此现在只能使用两种方法变体:clipRect / clipPath(代表Region.Op.INTERSECT)和clipOutRect / clipOutPath(代表Region.Op.DIFFERENCE)。要实现与Region.Op.REPLACE类似的功能,必须使用save()restore()方法:

canvas.save();        // IMPORTANT: save current state of clip and matrix (i.e. unclipped state) (let's say it's state #1)
canvas.clipRect(0, 0, 100, 100); // do some clipping
canvas.drawLine(...); // do some clipped drawing
canvas.restore();     // IMPORTANT: get back to previously saved (unclipped) state of the canvas (restores state #1)

canvas.save(); // now save again the current state of canvas (clip and matrix) (it's state #2)
canvas.clipRect(200, 200, 400, 400); // now we can do some other clipping (as we would do with Region.Op.REPLACE before)
canvas.drawLine(...); // and some other drawing
canvas.restore(); // get back go previously saved state (to state #2)

注意Canvas内部使用堆栈,因此您甚至可以在不同时刻多次调用save()。您只能拨打canvas.restore()次来调用canvas.save()次。

同样重要的是,调用canvas.restore()会更改剪辑矩形(与调用canvas.save()时的值相同)。因此,您必须在需要应用裁剪的所有绘图方法之后仔细放置restore()调用。

2:可能是因为一些性能优化。我想我读到了某个地方(我现在找不到),对于GPU上的硬件加速,他们只能使用INTERSECT / DIFFERENCE剪辑操作,其他必须回退到CPU处理。这可能是原因。

编辑:Here是一个相关的答案,因为ICS启用了硬件加速,所以不支持某些ClipRect操作。

3:正如他们在文档中所述,它将停止在Android P中运行(可能仅在定位Android P时):

  

自API Level API级别Build.VERSION_CODES.P起,只有INTERSECT和DIFFERENCE是有效的Region.Op参数。