为什么在invalidate之后直接调用requestLayout

Ers*_*man 13 android android-view android-view-invalidate

我正在学习自定义视图,并希望了解invalidate()requestLayout().

请参考这个答案及其图表:

/sf/answers/1809237041/

invalidate() 告诉Android视图的状态已经改变,需要重新绘制.

requestLayout() 表示视图的大小可能已更改,需要重新测量,然后重新绘制.

invalidate()将调用dispatchDraw(),draw()onDraw()因此重新呈现视图.

requestLayout() 另一方面,从测量再到再次渲染,几乎可以做任何事情.

为什么那么多的例子(甚至是TextView源代码)都会调用invalidate(),然后requestLayout()就在下一行呢?

Mic*_*use 11

invalidate()专门用于重绘视图内容.重绘不会同步发生.相反,它会将视图区域标记为无效,以便在下一个渲染周期中重绘它.

requestLayout()应该在其中的某些东西可能改变其尺寸时使用.在这种情况下,父视图和视图层次结构中的所有其他父项将需要通过布局传递重新调整自己.

如果您没有对您的视图做任何会改变其大小的事情,那么您不必打电话requestLayout().

如果您回过头来查看代码TextViewrequestLayout()要调用的位置的位置,那么它将会受到影响视图边界的方法的影响.例如,setPadding(),setTypeface(),setCompoundDrawables(),等.

因此,在requestLayout()调用时,它应该与对invalidate的调用配对,以确保重绘整个视图.

  • 我还不清楚为什么您还要调用`requestLayout()`时调用`invalidate()`。看起来`requestLayout()`总是会导致整个视图被重绘;除此之外,调用invalidate()似乎是多余的。 (2认同)
  • @ErsenOsman _“我必须调用invalidate()来呈现该新文本,以便显示该新文本。” _我的意思是,该声明并不完全正确;调用`requestLayout()`(不带`invalidate()`)也将渲染新文本。所以,我的问题是,在需要调用“ requestLayout()”的情况下,为什么还要调用“ invalidate()”? (2认同)

Sur*_*gch 9

看到下面的图表后,我的印象是调用requestLayout()最终会导致onDraw.

在此输入图像描述

因此,没有必要将这些称为一起,因为它是多余的.

invalidate();
requestLayout();
Run Code Online (Sandbox Code Playgroud)

然而,事实证明该图表具有误导性.有些视图实际上可能会在布局更改时自行失效,但这不是确定的.不能保证呼叫被调用.requestLayout()onDraw

我的来源(感谢此评论)是Romain Guy(Google的Android工程师):

requestLayout()本身不会导致绘图传递,但是某些视图可能会通过调用invalidate来对布局更改做出反应.

因此,要确定重新布局会导致重绘,那么您应该invalidate()与之配对requestLayout().(但事实并非如此.如果你只需要重绘,那么就没有必要打电话了requestLayout().一个人invalidate()会这么做.)