何时需要在视图上执行invalidate()?

我对这个问题的回答刚刚被接受,但是我开始怀疑什么时候确切地需要使一个视图无效(invalidate()),什么时候没有必要?

经过一番思考,我意识到它应该或多或少像这样工作:

  • onResume()之后发生“一切”的实际绘制
  • 在“空闲”时间内,可以重绘屏幕的一部分,但只能重绘那些是onResume()(以及下面的所有内容)的部分

因此,如果我在onResume()之后进行了一些更改(例如,作为对按钮单击的响应,则应该更改为invalidate())(应该是invalidate())。

然而,从这个问题的斯堪纳说的话,它肯定比这更复杂,并且它取决于某些理论,而后者取决于一种方法。

例如。 关于是否使用

lastClicked.setImageBitmap();

要么

lastClicked.setImageResource();

那么,当有必要在View上执行invalidate()时,它实际上是如何工作的呢?

4个解决方案
77 votes

(请考虑接受一些答案)

通常,invalidate()的意思是“在屏幕上重绘”,并导致调用视图的invalidate()方法。 因此,如果某些内容发生更改并且需要在屏幕上反映出来,则需要调用invalidate()。但是,对于内置窗口小部件,很少(如果有的话)需要自己调用它。 当您更改窗口小部件的状态时,内部代码将在必要时调用invalidate(),您的更改将反映在屏幕上。 例如,如果您调用TextView.setText(),则在进行了大量内部处理(该文本是否适合屏幕显示,是否需要省略等)之后,TextView将在setText()返回之前调用invalidate()。 其他小部件也是如此。

如果实现自定义视图,则每当支持模型发生更改并且需要重新绘制视图时,都需要调用invalidate()。 它也可以用于创建简单的动画,在其中更改状态,然后调用invalidate(),再次更改状态,依此类推。

Nikolay Elenkov answered 2020-08-01T12:31:54Z
23 votes

通常,系统会自动为您的小部件处理调整大小,隐藏,显示以及其他大量操作,但是如果绘制像素或支持数据的基础缓冲区已更改或过时(您在View或 原始数据集发生更改)。 发生这种情况是因为OS无法以某种特定方式知道数据已更改。

在这些情况下,您在处理绘图时,必须使用Widget.invalidate()告诉系统其基础数据状态不佳,并且正如您提到的,重新绘图在主线程上排队。 根据系统实现和Android版本的不同,系统所跟踪的更改有所不同,但我通常所做的是假定未跟踪系统资源(字节数组,char数组,资源索引,上下文上的手动绘制),并且需要使它们无效 其他所有内容都将由系统处理。

Srdjan Grubor answered 2020-08-01T12:31:24Z
0 votes

请记住,在屏幕上绘制是一个经常的过程,每当您更新视图时,都应传播并重新绘制更改以通知这种更改权。 invalidate()是一种触发方法,该信号会强制重绘您要显示其更改的任何视图。

Remario answered 2020-08-01T12:32:15Z
0 votes

当我想绘制textPaint时遇到了这个问题!我的代码是

    canvas.drawPaint(textPaintNumber)
    canvas.drawText("MyText", 30F, 63F, textPaintNumber)

我清除了第一个皮棉并解决了问题

    canvas.drawText("MyText", 30F, 63F, textPaintNumber)
Maryam Azhdari answered 2020-08-01T12:32:39Z
translate from https://stackoverflow.com:/questions/10647558/when-its-necessary-to-execute-invalidate-on-a-view