Android性能典范渲染篇 — — 6.clipRect()和quickReject()使用介绍

It’s worth pointing out that the Android framework knows that overdraw is a problem, and will go out of its way to avoid drawing UI widget that may be invisible in the final image.This type of optimization, called clipping, is highly important to UI performance.

值得指出是Android Framework 会判断界面是否有过度重绘的问题。并且能够以它自己的方式去避免绘制那些没有在最终图像上显示的UI组件。那种类型的优化对于UI性能非常重要,我们叫截断绘制。

If you can determine an object will be fully obscured, there’s no reason to go about drawing it. In fact this is actually one of the most important performance optimization that Android performs.

因为如果能够确定一个UI组件将会被完全被遮盖,绘制它是完全没有必要的。实际上这对于Android系统的运行也是一个很重要的性能优化。

But sadly this technique doesn’t extend itself to complex custom views, where you’re overriding the canvas dot on draw method. In these cases, the underlying system doesn’t have insight into how you’re drawing your content, which makes it really hard for it to remove hidden views from your rendering pipeline.

但遗憾的是,对于比较复杂的自定义view而言,即使覆写Canvas类的onDraw(),也享受不到这样的优化技术。这样的话,底层系统就不会觉察到自定义view是具体怎样绘制的,导致从渲染途径入手去移除隐藏的view真的很难。

For example,in this stack of cards, only the top card is fully visible and the rest of the cards are mostly hidden, which means that drawing all of those overlapping pixels is wasted processing time. To address this problem, the canvas class is equipped with a few special methods that you can use to tell the Android Framework what parts of the canvas are hidden and don’t need to be drawn.

举个例子,在这些卡片中,只有顶部的卡片式是完整显示,而其余的卡片则是大部分被隐藏,而绘制这些重叠的像素点是在浪费时间。为了解决这个问题,Canvas类里有几个特殊的方法,可以用来告诉Android Framework 在自定义view中哪些部分是隐藏而不需要被绘制的。

The most useful method is canvas dot clipRect, which allows you to define the drawable boundaries for a given view, meaning that if any canvas drawing happens outside these boundaries, it’ll be ignored. This could be really helpful when you’ve got this type of staggered view, like our cards for example.

Canvas类里最有用处的方法是clipRect(),它让你去决定给定view可绘制的边界,确定后任何在画布边界之外的绘制,都将被忽略。像我们示例中的卡片一样,当你使用这种重叠交错的自定义view时,这个方法真的会有帮助。

If you know how much of your custom view is visible, or rather you know how much is obscured, you can define the clipRect boundaries, which will prevent any drawing from happening in the obscured areas.

对于自定义view而言,与其说你知道有多少区域要显示,倒不如说你知道多少区域被遮盖,使用clipRect()用来确定绘制边界,会防止遮盖区域的任何绘制发生。

Now the clipRect API helps the system know what to avoid drawing.But it would also be helpful for your custom view to do some of this work on its own, ahead of time for example, it would be really helpful if you knew what you were going to draw if it’s actually outside of the clipping rectangle.

Fortunately, you don’t have to figure out all that intersection logic yourself, the canvas.quickReject method tests whether a given area is completely outside the clipping rectangle, in which case you can skip all that drawing work. Now let’s take a look at a common situation where this happens and take a swing at fix it.

现在clipRect()帮助系统知道什么为了避免绘制。但是他应该也有用于你自定义view将要一些这个工作它自己,举个例子,他愿意真的有帮助的如果你知道什么你将要去绘制如果它是实际上在剪切矩形的外面。

幸运的是,不需要你自己去算出所有的相交逻辑,Canvas类的quickReject()会测试一个给定区域是否能完整的显示矩形画布中,在这种情况下,你可以跳过所有的绘制工作。现在让我们看一下在一般情况下,它是怎样发生并修复的。

Show your support

Clapping shows how much you appreciated seanutf’s story.