2012-05-18 29 views
26

我对this question的回答刚刚被接受,但我开始怀疑究竟是什么时候需要使视图无效()而视图没有必要?何时需要在View上执行invalidate()?

后一点思考我来实现它应该工作或多或少是这样的:

  • 的“一切”实际绘图发生后onResume()
  • 中的“自由”时间部分
  • 屏幕可以重绘,但只有那些被invalidated(和下面的一切)

因此,它似乎是,如果我后改变一些东西(例如作为对按钮点击的回应,我应该invalidate()更改为View)。

但是,从this question中的scana中可以看出,它必须更复杂一些,它取决于某些方法使用的方法。

E.g.一个人是否使用

lastClicked.setImageBitmap(); 

lastClicked.setImageResource(); 

所以,当有必要在一个视图下执行无效(),它是如何真的有效吗?

回答

13

通常,系统会自动处理调整大小,隐藏,显示和其他大量其他内容如果绘制像素或后备数据的基础缓冲区已更改或陈旧(您交换View上的图像资源或原始数据集更改),则它有时会出现问题。发生这种情况的原因是操作系统无法知道数据是以特定方式更改的。

在这种情况下,你正在处理的图纸,你必须告诉其底层的数据是不符合Widget.invalidate(良好的状态的系统)和重画被排队的主线程只是如你所说。根据系统实现和Android版本,跟踪系统更改的内容会有所不同,但我通常所做的是假定系统资源(字节数组,字符数组,资源索引,上下文的手动绘图)未被跟踪,并且需要一个无效和其他一切将由系统处理。

+0

一些更正句子,但错误的方法。 -1 – ncm

54

(不要考虑接受一些答案)

一般来说,invalidate()手段和结果“的屏幕重绘”到视图的onDraw()方法的调用。所以如果有什么变化,需要在屏幕上反映出来,你需要拨打invalidate()。但是,对于内置小部件,您很少需要自己调用它。当您更改小部件的状态时,内部代码将根据需要调用invalidate(),您的更改将反映在屏幕上。例如,如果您拨打TextView.setText(),在进行了大量内部处理后(文本是否适合屏幕,是否需要椭圆化等),TextView将在setText()返回之前调用invalidate()。对于其他小部件也是如此。

如果您实现自定义视图,则只要支持模型发生更改并需要重绘视图,就需要调用invalidate()。它也可以用来创建简单的动画,在那里你改变状态,然后调用invalidate(),再次更改状态等。

+1

要完成这个答案我想说很多时间是很重要的,以检查您可能使用的小部件的各种方法的代码,以了解何时有无效呼叫并实施布局,以尽量减少它们。 例如,如果你有一个复杂的布局,一个带有wrap_content的TextView将始终invalide()所有你的布局每一次调用setText()的结束,另一端如果你设法得到一个固定的维度,该视图将随着更流畅的GUI而改变。 –

0

请记住,在屏幕上绘图是一个频繁的过程,无论何时更新视图,都应该传播和重绘该更改以通知此类更改。 invalidate()是一个触发器方法,它表示强制重绘任何您希望显示更改的视图。