Android View.onDraw() --- 它什么时候被调用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11912406/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 09:09:30  来源:igfitidea点击:

View.onDraw() --- when does it get called?

androidgraphicsondraw

提问by CptSupermrkt

I put a Log.d() call into the onDraw() of my extended View, so I could see how often and when it's getting called. It gets called upon instantiation of the view, which is not surprising. But then I notice, it gets called on every tap that is handled by onTouchEvent(), even though my code there isn't doing anything remotely related to graphics. However, in the documentationfor Views, I can't seem to find anything about when onDraw() is actually called. I'm not really concerned about my particular project here (this doesn't cause a problem for me), I would just like to know if there is a list somewhere or something that shows the order of operations for a View, particularly what causes onDraw() to get called.

我将 Log.d() 调用放入扩展视图的 onDraw() 中,这样我就可以看到它被调用的频率和时间。它在视图的实例化时被调用,这并不奇怪。但后来我注意到,它在 onTouchEvent() 处理的每次点击时都会被调用,即使我的代码没有做任何与图形相关的远程操作。但是,在Views的文档中,我似乎找不到有关 onDraw() 何时被实际调用的任何信息。我并不真正关心我在这里的特定项目(这对我来说没有问题),我只想知道某处是否有列表或显示视图操作顺序的东西,特别是什么原因onDraw() 被调用。

回答by Raghav Sood

AFAIK, a View's onDraw() is called when:

AFAIK,在以下情况下调用视图的 onDraw():

  1. The view is initially drawn
  2. Whenever invalidate()is called on the view
  1. 最初绘制视图
  2. 每当在视图上调用invalidate()

Invalidate can be called by you or the system whenever needed. For example, a lot of Views change how they look onTouch, like an EditText getting an outline and cursor, or a button being in the pressed state. Due to this, Views are redrawn on touch.

Invalidate 可以在需要时由您或系统调用。例如,许多视图会改变它们在触摸时的外观,例如 EditText 获得轮廓和光标,或者按钮处于按下状态。因此,视图会在触摸时重绘。

I agree that it would be nice to have a document that detailed the working of Views, and if one exists and somebody knows where to find it, please let us know.

我同意最好有一份详细说明视图工作的文档,如果存在并且有人知道在哪里可以找到它,请告诉我们。

回答by Chad Bingham

onDraw()is called when invalidate()is called.

onDraw()被调用时invalidate()被调用。

But you should know for ViewGroups: onDraw()will not be calledlike you expect. Rather, onDispatchDraw().

但是您应该知道 ViewGroups:onDraw()不会像您期望的那样被调用。而是,onDispatchDraw()

However, in a ViewGroup you can call setWillNotDraw(false)in the constructor to make onDraw()to be called on invalidate().

但是,在 ViewGroup 中,您可以setWillNotDraw(false)在构造函数中调用以使其onDraw()被调用invalidate()

Take a look at this answer

看看这个答案

回答by hasanghaforian

  • If you set a background drawable for a View, then the View will draw it for you before calling back to its onDraw() method.

  • onAttachedToWindow () is called when the view is attached to a window. At this point it has a Surface and will start drawing. Note that this function is guaranteed to be called before onDraw(android.graphics.Canvas), however it may be called any time before the first onDraw -- including before or after onMeasure(int, int).

  • invalidate() mark the area defined by dirty as needing to be drawn. If the view is visible, onDraw(android.graphics.Canvas) will be called at some point in the future.

  • 如果您为 View 设置了可绘制的背景,那么 View 会在回调其 onDraw() 方法之前为您绘制它。

  • 当视图附加到窗口时调用 onAttachedToWindow()。此时它有一个 Surface 并且将开始绘制。请注意,此函数保证在 onDraw(android.graphics.Canvas) 之前被调用,但是它可以在第一个 onDraw 之前的任何时间被调用——包括在 onMeasure(int, int) 之前或之后。

  • invalidate() 将dirty 定义的区域标记为需要绘制。如果视图可见, onDraw(android.graphics.Canvas) 将在未来的某个时间点被调用。

回答by Gagandeep Singh

One important thing to keep in mind is that try to minimize calling of invalidate() function with no arguments. Instead try to maximize the invalidate() function with four arguments.As drawing whole view is very expensive.The second variant refreshes only the part of view.

要记住的一件重要事情是尽量减少不带参数的 invalidate() 函数的调用。而是尝试使用四个参数最大化 invalidate() 函数。因为绘制整个视图非常昂贵。第二个变体仅刷新视图的一部分。

回答by Bad Loser

Additional to the above: The soft keyboard causes a View.invalidate()-->View.onDraw()sequence after resizing the Window to sensibly accommodate the 'keyboard'. A custom View.onDraw()must leave itself in a state that anticipates this possibility.
Such phenomenum explains why the app you developed and tested on a tablet with a bluetooth keyboard went to the dogs once it reached the real world (-:

除上述之外:软键盘在调整窗口大小以适应“键盘”后会导致View.invalidate()-->View.onDraw()序列。自定义View.onDraw()必须让自己处于预期这种可能性的状态。
这样的现象解释了为什么您在带有蓝牙键盘的平板电脑上开发和测试的应用程序在到达现实世界后就会被狗使用(-: