57

我对这个问题的回答刚刚被接受,但我开始想知道什么时候需要使视图无效,什么时候不需要?

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

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

因此,看起来,如果我在之后更改某些onResume()内容(例如,作为对按钮单击的响应,我应该invalidate()更改View)。

但是,从这个问题中的scana所说的来看,它一定比那更复杂,并且它有时取决于使用什么方法。

例如关于一个人是否使用

lastClicked.setImageBitmap();

或者

lastClicked.setImageResource();

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

4

4 回答 4

95

(请考虑接受一些答案)

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

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

于 2012-05-18T06:27:54.230 回答
30

通常,系统会自动为您的小部件处理调整大小、隐藏、显示和大量其他事情,但如果绘制像素或支持数据的底层缓冲区已更改或陈旧(您交换视图上的图像资源或原始数据集更改)。发生这种情况是因为操作系统无法知道数据以它所做的特定方式更改。

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

于 2012-05-18T06:37:01.453 回答
0

Please remember that drawing on the screen is frequent process, whenever you update a view, that change should be propogated and redrawn to notify such change right. invalidate() is a trigger method,that signals force reDrawing of any view you wish to show changes for.

于 2017-09-15T16:00:38.880 回答
0

I had this problem when I wanted to draw a textPaint! My code was

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

I cleared the first lint and the problem was solved

    canvas.drawText("MyText", 30F, 63F, textPaintNumber)
于 2019-01-24T17:12:33.113 回答