看起来Android真的不喜欢invalidate (Rect dirty)
,它用于使画布的一部分无效。当我使画布的一部分(如下图绿色)无效并且需要同时重绘画布的ToggleButton
外部时,以红色显示的整个区域都将被擦除!似乎 Android 只是使包含需要重绘的两个区域的联合的最小矩形内的所有内容无效,即使其中一个区域位于我要使其无效的画布的视图之外。
这是标准行为吗?如果是这样,为什么有人会使用部分失效?
看起来Android真的不喜欢invalidate (Rect dirty)
,它用于使画布的一部分无效。当我使画布的一部分(如下图绿色)无效并且需要同时重绘画布的ToggleButton
外部时,以红色显示的整个区域都将被擦除!似乎 Android 只是使包含需要重绘的两个区域的联合的最小矩形内的所有内容无效,即使其中一个区域位于我要使其无效的画布的视图之外。
这是标准行为吗?如果是这样,为什么有人会使用部分失效?
Android 有一个名为ViewRootImpl
. 此类由您在屏幕上看到的每个窗口所拥有(术语窗口在这里有点混乱,因此对于这个解释,窗口是主要活动的布局,顶部没有任何对话框或弹出窗口)。这个布局一直在被遍历,这意味着 Android 只是在等待这个窗口有一个脏矩形并绘制它。由于此窗口可能包含许多视图(按钮等),因此它会遍历所有视图并询问每个视图是否需要重绘。每个视图都返回一个脏矩形ViewRootImpl
,所有这些矩形都连接到一个最后重绘的大矩形。
为什么这样做?好吧,ViewRootImpl
要求WindowManagerService
一个Canvas
人借鉴。这意味着Canvas
每次遍历时,一个窗口中的所有视图实际上都共享一个。
至于你的问题,如果只有一个特定View
的有一个脏矩形,那么只会绘制那个脏矩形,但是由于另一个视图也有一个,所以脏矩形包含两者。
此问题是由硬件加速引起的。您必须在活动中禁用它才能使用invalidate(dirty rect)
. 要在您的活动中禁用硬件加速,请打开清单文件并添加:
android:hardwareAccelerated="false"
现在您可以使用invalidate(dirty rect)
.