是否应该在 invalidate(l,t,r,b) 之后显式设置剪辑区域?

Posted

技术标签:

【中文标题】是否应该在 invalidate(l,t,r,b) 之后显式设置剪辑区域?【英文标题】:Should the clip region be explicitly set after invalidate(l,t,r,b)? 【发布时间】:2016-03-27 14:55:21 【问题描述】:

那里的文档似乎表明,如果您使View 的多个区域无效(使用invalidate(l,t,r,b)),则无需在onDraw() 方法中使用剪辑区域指定这些区域。

另一方面,我见过很多自定义视图的示例,它们在使该区域无效的同时维护一个脏区域,然后使用该脏区域在onDraw() 方法中剪切画布(参见示例, the KeyBoardView class)

有关此问题的文档是否不完整? invalidate()clipRect() 应该一起使用吗?

【问题讨论】:

【参考方案1】:

不需要与clipRect() 同时使用invalidate()。有时您可以单独使用它们,有时您可以一起使用它们。

作为 View 上的一个方法,invalidate() 在整个 View 的级别上工作。像这样使区域失效会导致 android 仅重绘已失效的区域,因此您推送的像素会因更改而减少。

作为 Canvas 上的一个方法,clipRect() 会更改该 Canvas 上后续绘制操作的有效绘图空间。这使您可以执行绘制操作,而无需调整计算以仅影响有限的空间。画布将确保如果您在该空间之外绘制,它将无效。您还可以累积剪辑区域以创建非矩形剪辑区域。

画布不必与视图相关联。很多时候你只是想画一个位图供以后使用。因此,在 Canvas 上使用 clipRect() 可能与 View 有任何关系,也可能没有任何关系,即便如此,也可能与该视图的失效有关,也可能没有任何关系。如果您想将两者一起用作非常大的绘图空间的优化,您将必须确保视图的无效区域等同于画布的剪辑区域,这并不总是直截了当的,因为剪辑区域是并不总是简单的矩形。

【讨论】:

Canvas 部分对我来说很清楚。无效的解释没有那么多。你说invalidate(...) 导致android 只重绘一个区域。它是如何完成的?我怎么能从onDraw() 中知道要绘制的无效区域是什么?或者我应该编写代码来绘制整个视图,而 android 只会绘制无效区域? (听起来很像clipRect()

以上是关于是否应该在 invalidate(l,t,r,b) 之后显式设置剪辑区域?的主要内容,如果未能解决你的问题,请参考以下文章

poj1195(二维树状数组)

R中的二尾和一尾T检验

bzoj4918: 回文数对

BZOJ.2453.维护队列([模板]带修改莫队)

Codeforces 536ATavas and Karafs

输入6到16位字母与数字组合应该怎样输?