用Region.Op.REPLACE`替代`canvas.clipRect`的最佳选择是什么? [英] What is the best alternative to `canvas.clipRect` with `Region.Op.REPLACE`?

查看:320
本文介绍了用Region.Op.REPLACE`替代`canvas.clipRect`的最佳选择是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个具有很多画布图形而不是多个视图的库(可用 此处 ).

I'm working on a library that has a lot of canvas drawing instead of multiple views (available here).

在我进行改进以使其能够满足应用程序的需求(需要进行一些自定义)的过程中,我注意到有些行被标记为已弃用:

As I work to improve it and make it work for our needs of the app (need some customization), I've noticed there are some lines that are marked as deprecated:

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

事实是,我认为没有一个合适的候选人可以用较新的API代替这一行代码

Thing is, I don't think there is a good candidate to replace this line of code with the newer APIs

查看 文档 ,它是这样写的:

Looking at the docs, this is what's written:

此方法在API级别26中已弃用.Region.Op值other 比INTERSECT和DIFFERENCE具有扩展剪辑的能力.这 画布剪辑API仅用于扩展剪辑 还原操作.这使视图父级可以将画布剪辑到 清楚地定义其子项的最大绘图区域.这 推荐的替代调用是clipRect(RectF)和 clipOutRect(RectF);

This method was deprecated in API level 26. Region.Op values other than INTERSECT and DIFFERENCE have the ability to expand the clip. The canvas clipping APIs are intended to only expand the clip as a result of a restore operation. This enables a view parent to clip a canvas to clearly define the maximal drawing area of its children. The recommended alternative calls are clipRect(RectF) and clipOutRect(RectF);

因此,我尝试使用这两个功能中的任何一个,但是这两个功能在绘制外观时都引起了问题.

So I tried using either of those functions, yet both of them caused issues with the drawing of how it used to be.

看一下弃用,似乎该函数本身已被标记,但没有标记Region.Op.REPLACE:

Looking at the deprecation, it seems that the function itself is marked, but not Region.Op.REPLACE :

所以也许真的没有其他选择...

So maybe it doesn't really have an alternative...

  1. 在这种情况下最好的选择是什么?
  2. 为什么过时了?
  3. 与某些不推荐使用的功能相反,我认为在找不到替代方法的情况下仍可以安全使用此功能,对吧?

推荐答案

1:现在已弃用所有使用自定义Region.Op的方法,因此现在只能使用两个方法变体:clipRect/clipPath(其中代表Region.Op.INTERSECT)和clipOutRect/clipOutPath(代表Region.Op.DIFFERENCE).要实现类似于Region.Op.REPLACE的功能,必须使用save()restore()方法.

1: All methods that use custom Region.Op are deprecated now, so one can use only two method variants now: clipRect/clipPath (which represents Region.Op.INTERSECT) and clipOutRect/clipOutPath (which represents Region.Op.DIFFERENCE). To achieve function similar to Region.Op.REPLACE one must use save() and restore() methods.

因此,在以前(使用Op.REPLACE),您只需拨打:

So previously (with Op.REPLACE) you would call just:

canvas.clipRect(0, 0, 100, 100); // do some clipping
canvas.drawLine(...); // do some clipped drawing

canvas.clipRect(200, 200, 400, 400, Region.Op.REPLACE); // replace clipping region to completely different one
canvas.drawLine(...); // and some other drawing

但是现在您必须手动保存和恢复以前的画布状态:

But now you have to save and restore previous canvas state manually:

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().

Note Canvas is internally using stack, so you can even call save() multiple times at different moments. You just can't call canvas.restore() more times than the canvas.save() was called.

另一个重要的注意事项是,对canvas.restore()调用会更改片段rect (与调用canvas.save()时的值相同).因此,您必须小心地将restore()调用放置在所有需要应用裁剪的绘制方法之后.

Also important note is that call to canvas.restore() changes the clip rect (to the same value it was when canvas.save() was called). So you must carefully place the restore() call after all the drawing methods that needs the applied clipping.

2:可能是由于某些性能优化.我想我读过某处(我现在找不到),因为要在GPU上进行硬件加速,它们只能使用INTERSECT/DIFFERENCE片段操作,而其他操作必须回落到CPU处理.那可能就是原因.

2: Probably because of some performance optimizations. I think I read somewhere (I couldn't find it now) that for hardware acceleration on GPU they can use only INTERSECT / DIFFERENCE clip operations and other ones must fall-back to CPU processing. That might be the reason.

此处是一些相关的答案,即由于ICS具有启用的硬件加速功能,因此不支持某些ClipRect操作.

Here is some related answer, that since ICS with enabled HW acceleration some ClipRect ops are not supported.

3:就像他们在文档中所说的那样,它将停止在Android P中运行(可能只有在定位Android P时才如此):

3: As they say in documentation, it will stop working in Android P (probably only when targeting Android P):

从API级别开始,仅API级别Build.VERSION_CODES.P INTERSECT和DIFFERENCE是有效的Region.Op参数.

As of API Level API level Build.VERSION_CODES.P only INTERSECT and DIFFERENCE are valid Region.Op parameters.

这篇关于用Region.Op.REPLACE`替代`canvas.clipRect`的最佳选择是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆