我将 Log.d() 调用放入扩展视图的 onDraw() 中,这样我就可以看到它被调用的频率和时间。它在视图的实例化时被调用,这并不奇怪。但后来我注意到,它会在 onTouchEvent() 处理的每个点击上被调用,即使我的代码没有做任何与图形远程相关的事情。但是,在 Views 的文档中,我似乎找不到任何关于何时实际调用 onDraw() 的信息。我并不真正关心我在这里的特定项目(这对我来说不会造成问题),我只想知道某处是否有一个列表或显示视图操作顺序的东西,特别是什么原因onDraw() 被调用。
6 回答
AFAIK,视图的 onDraw() 在以下情况下被调用:
- 最初绘制视图
- 每当在视图上调用invalidate()
您或系统可以在需要时调用 Invalidate。例如,许多 View 会改变它们在 Touch 上的外观,例如 EditText 获得轮廓和光标,或者按钮处于按下状态。因此,视图会在触摸时重绘。
我同意拥有一份详细说明 Views 工作的文档会很好,如果存在并且有人知道在哪里可以找到它,请告诉我们。
onDraw()
被调用时invalidate()
被调用。
但是你应该知道 ViewGroups:onDraw()
不会像你期望的那样被调用。而是,onDispatchDraw()
。
但是,在 ViewGroup 中,您可以setWillNotDraw(false)
在构造函数中调用 make onDraw()
to be called on invalidate()
。
看看这个答案
如果您为 View 设置了背景可绘制对象,则 View 将在回调其 onDraw() 方法之前为您绘制它。
onAttachedToWindow () 在视图附加到窗口时调用。此时它有一个 Surface 并将开始绘制。请注意,保证在 onDraw(android.graphics.Canvas) 之前调用此函数,但是它可以在第一个 onDraw 之前的任何时间调用——包括在 onMeasure(int, int) 之前或之后。
invalidate() 将dirty定义的区域标记为需要绘制。如果视图可见,onDraw(android.graphics.Canvas) 将在未来的某个时间点被调用。
要记住的一件重要事情是,尽量减少不带参数的 invalidate() 函数的调用。而是尝试使用四个参数最大化 invalidate() 函数。因为绘制整个视图非常昂贵。第二个变体仅刷新视图的一部分。
除上述内容外:软键盘在调整窗口大小以合理地适应“键盘”后会导致View.invalidate()-->View.onDraw()序列。自定义View.onDraw()必须让自己处于预期这种可能性的状态。
这样的现象解释了为什么您在带有蓝牙键盘的平板电脑上开发和测试的应用程序一旦到达现实世界就会被狗追捕(-:
何时调用 onDraw(查看此以获取更多详细信息)
每当 android 认为您的视图应该重绘时,就会调用 onDraw 方法。这可能是您的视图动画时的情况,在这种情况下,动画中的每一帧都会调用 onDraw。当布局更改并且您的视图在屏幕上重新定位时也会调用它。
但是,如果您的视图中的某些数据发生了更改,并且您想确保重新绘制视图,该怎么办。你不能直接调用 onDraw 。相反,您应该调用 invalidate 来告诉视图它需要重绘自身。