【问题标题】:android view viewgroup invalidate ondraw and drawandroid view viewgroup 使ondraw和draw无效
【发布时间】:2025-12-29 13:40:12
【问题描述】:

我们正在尝试编写自己的 MapView,我正在尝试弄清楚向 mapview 添加叠加层如何导致它们在其他映射 API 中被绘制

我有一个扩展 ViewGroup 的 MapView。我想我已经发现调用 MapView.invalidate() 会导致调用 mapview 的 dispatchDraw 方法。听起来对吗?

如果是这样,mapview的onDraw和draw方法是什么时候调用的?

更重要的是所有这些视图以及在任何地方都记录良好时调用哪些方法?

谢谢!

编辑 This SO post 解释说,对于扩展 ViewGroup 的类,不会自动调用 onDraw 方法。如果你需要它,你必须强迫它。但是正如ebarrenchea指出的那样,如果调用了所有方法,顺序是draw,onDraw,dispatchDraw

【问题讨论】:

    标签: android view ondraw


    【解决方案1】:

    在您的视图组上调用invalidate 将强制draw 运行,这将依次调用onDrawdispatchDraw。您应该查看查看文档here 和查看源代码here 了解更多信息。

    【讨论】:

    • 是的,我看到了那个页面,但是那里没有说“调用无效导致......发生”。所以当我调用mapView.invalidate时,先执行mapview的onDraw,再执行mapView的draw,再执行mapView的dispatchDraw,对吗?
    • 那里的文档指出“如果视图是可见的,onDraw(android.graphics.Canvas) 将在未来的某个时候被调用。”并查看查看源代码状态,onDraw 是从 draw 调用的,并且在 dispatchDraw 之后将被调用,如您所见 here
    • 嗯,我第一次错过了源代码链接。我阅读了该文件并查看了文档,这是有道理的,但似乎从未调用过我的 onDraw 方法!我在那里有一个日志语句,所以我可以看到它何时发生,但它从来没有写过..知道为什么不会调用 onDraw 吗?视图是可见的,它就是屏幕上的东西!
    • 源链接以前不存在,我不久前编辑了答案。为什么您的onDraw 从未被调用有两种可能性:1) 您的invalidate 调用从未被触发; 2)你覆盖了draw(你真的不应该这样做)并且把事情搞砸了。您可能应该看看是什么触发了您的invalidate 呼叫,并确保它确实发生了。
    【解决方案2】:

    invalidate() 必须从 UI 线程调用以导致 onDraw()。尝试使用postInvalidate(),它应该与invalidate() 具有相同的效果,但适用于非 UI 线程。

    【讨论】: