什么时候需要在View上执行invalidate()?

mja*_*ski 44 android android-imageview android-view

我对这个问题的回答刚刚被接受,但我开始想知道究竟是什么时候需要使一个视图无效(以及什么时候没有必要)?

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

  • 实际绘制的"一切"发生在之后 onResume()
  • 在"免费"时间屏幕的部分可以重绘,但只有那些invalidated(和下面的一切)

因此,看起来,如果我改变后的东西onResume()(例如作为对按钮点击的响应,我应该invalidate()改变View).

但是,从这个问题中的 scana所说,它必须比那更复杂,并且它取决于某些人使用的方法.

例如,是否使用

lastClicked.setImageBitmap();
Run Code Online (Sandbox Code Playgroud)

要么

lastClicked.setImageResource();
Run Code Online (Sandbox Code Playgroud)

那么,什么时候需要在View上执行invalidate()以及它是如何工作的呢?

Nik*_*kov 77

(考虑接受一些答案)

通常,invalidate()意味着"在屏幕上重绘"并导致调用视图的onDraw()方法.因此,如果某些内容发生变化并且需要在屏幕上反映出来,则需要致电invalidate().但是,对于内置小部件,您很少需要自己调用它.当您更改窗口小部件的状态时,内部代码将invalidate()根据需要调用,您的更改将反映在屏幕上.例如,如果TextView.setText()在进行大量内部处理(文本是否适合屏幕,是否需要省略等)之后TextView调用,则会invalidate()setText()返回之前调用.同样适用于其他小部件.

如果实现自定义视图,则需要invalidate()在支持模型更改时进行调用,并且需要重新绘制视图.它还可以用于创建简单的动画,您可以在其中更改状态,然后调用invalidate(),再次更改状态等.

  • 为了完成这个答案,我会说很多时候检查您可能在小部件上使用的各种方法的代码很重要,以了解何时存在无效调用并实现布局以最小化它们。例如,如果您有一个复杂的布局,一个带有 wrap_content 的单个 TextView 将在每次调用 setText() 结束时始终使您的所有布局无效,另一方面,如果您设法获得固定尺寸,只有视图内的文本将随着更加流畅的 GUI 的结果而改变。 (2认同)

Srd*_*bor 23

通常,系统会自动处理小部件的大小调整,隐藏,显示和大量其他事情,但如果绘制的像素或后备数据的基础缓冲区已更改或过时(在视图上交换图像资源或原始数据集更改).发生这种情况是因为操作系统无法知道数据以特定方式发生变化.

在你处理绘图的这些情况下,你必须告诉系统它的底层数据与Widget.invalidate()并没有处于良好状态,并且正如你所提到的那样,重新绘制在主线程上排队.根据系统实现和Android版本,系统更改跟踪的内容会有所不同,但我通常会假设系统资源(字节数组,字符数组,资源索引,上下文中的手动绘图)不会被跟踪,需要使用无效其他一切都将由系统处理.