我刚刚开始在 Android 中制作自定义视图,所以我还没有了解有关视图层次结构的绘制(绘制)周期以及有效使用 View 方法invalidate
和onDraw
. 但是我遇到了一个令人费解的行为。
我有一个自定义视图组,扩展了RelativeLayout类。这是我父母的看法。其中,作为孩子,我有几个自定义的子视图。有时,为了响应用户操作,我需要重绘这些视图的各个部分,包括父视图和子视图。
通常这是事件的顺序。在子视图类中,我通过调用invalidate(rct)
where rct 是分隔我需要更新的区域的 Rect 来使其一小部分区域无效。
令人费解的是,这种非常本地化的行动引发了真正过度的全球性反应。从我的 LogCat 跟踪输出的证据来看,这似乎是:
(1)整个父视图经历一次完整的重绘
其次是:
(2) 每个子视图都经历一次完整的重绘
诚然,如果响应 (1) 发生,那么 (2) 确实应该遵循,因为所有子视图都需要完全重新绘制。但是为什么(1)会发生呢?
这是视图层次结构的绘制周期的正常行为吗?如果是这样,那似乎就大错特错了! 相反,我本来希望只需要重绘父级的一小部分区域,直接位于要重绘的子视图中标记为脏的矩形下方。此外,即使是父级的那个小区域,也只有在覆盖的子级在该区域不是完全不透明的情况下才需要重绘。
这种看似零散的大规模重绘活动的证据是,在我的每个自定义视图的每个 onDraw 方法主体中,我都有一个 LogCat 跟踪语句,如下所示:
@Override
protected void onDraw(Canvas c) {
Rect rct = new Rect();
Boolean doDraw = c.getClipBounds(rct);
Log.v(LOGTAG, "onDraw Entry doDraw=" + doDraw + " rct=" + rct);
....
}
LogCat 输出清楚地表明,每个 onDraw 调用都是针对整个视图表面的。