Answers:
为了更好地理解FrançoisBOURLIEUX和Dalvik提供的答案,我建议您看一下Arpit Mathur的这张令人敬畏的视图生命周期图:

TextView。我想,也许他们想得出View最后一次他们改变其布局相关参数之前,但它并没有真正使任何意义,如果我们想在不同的顺序被调用这些电话(他们称之为invalidate()后立即requestLayout()在TextView以及)。也许值得在StackOverflow上提出另一个问题:)?
invalidate()和requestLayout())。这些方法的目的是告诉您发生了View什么样的失效(如您所说的)。View调用这些方法之一后,并不能决定要遵循的路径。选择View-lifecycle-path 的逻辑是选择适当的方法来调用自身。如果存在与尺寸更改有关的某些内容- requestLayout()应该调用,如果只有视觉更改而尺寸没有更改-您应该调用invalidate()。
View以某种方式更改大小,例如,获得a的当前LayoutParams值View并对其进行修改,但不调用requestLayout或setLayoutParams(requestLayout内部调用),则可以随意调用invalidate(),并且该View不会通过测量布局过程中,因此不会改变它的大小。如果您不告诉您View它的大小已更改(使用requestLayout方法调用),则Viewwill将假定它没有更改,并且onMeasureand onLayout将不会被调用。
invalidate()invalidate()当您要计划重绘视图时,调用完成。它将导致onDraw最终被调用(很快,但不是立即)。自定义视图何时调用的示例是文本或背景颜色属性已更改。
视图将被重绘,但大小不会改变。
requestLayout()如果关于视图的某些更改会影响大小,则应致电requestLayout()。这将触发onMeasure和onLayout不仅是这个观点,但一路上扬父视图的线。
不能保证调用requestLayout()会导致onDraw(与接受的答案中的图相反),因此通常将其与结合使用invalidate()。
invalidate();
requestLayout();
例如,自定义标签的text属性发生更改时。标签会改变尺寸,因此需要重新测量和重新绘制。
forceLayout()在requestLayout()父视图组上调用时,不需要重新测量并重传其子视图。但是,如果在重新测量和重排中应包括一个孩子,则可以呼叫forceLayout()该孩子。forceLayout()仅在子代requestLayout()与其直接父代一起出现时才对子代起作用。forceLayout()本身调用不会产生任何效果,因为它不会触发requestLayout()视图树。
阅读此问答以获取有关以下内容的详细说明forceLayout()。
View 源代码requestLayout()在invalidate()需要时致电。没有人做布局或立即绘制。相反,它们设置标志,最终将导致重新布局并重画。
在这里您可以找到一些响应:http : //developer.android.com/guide/topics/ui/how-android-draws.html
对我来说,invalidate()仅调用会刷新视图,而调用会requestLayout()刷新视图并计算屏幕上视图的大小。
这个答案是不正确的forceLayout()。
如您在代码中所见forceLayout()它仅将视图标记为“需要重新布局”,但是它既不计划也不触发该重新布局。重新布局将不会发生,直到将来某个时候由于其他原因布置视图的父级。
使用forceLayout()和时,还有一个更大的问题requestLayout():
假设您已经调用forceLayout()了一个视图。现在,当调用requestLayout()该视图的后代时,Android将递归调用requestLayout()该后代的祖先。问题在于它将在您调用的视图处停止递归forceLayout()。因此,该requestLayout()调用将永远不会到达视图根,因此也不会调度布局遍历。视图层次结构的整个子树都在等待布局,并且调用requestLayout()该子树的任何视图都不会导致布局。仅requestLayout()在该子树之外调用任何视图都会破坏该咒语。
我会考虑的实现forceLayout()(以及它如何requestLayout()被破坏,因此您永远不要在代码中使用该函数。
View并亲自遇到问题并对其进行调试来解决了。
forceLayout()API 的用途感到好奇:它实际上并没有强制执行布局传递,而只是更改了在中观察到onMeasure()的标志,但是onMeasure()除非被调用requestLayout()或显式调用,否则它不会被View#measure()调用。也就是说,forceLayout()应该与配对requestLayout()。另一方面,forceLayout()如果仍然需要执行,为什么还要执行requestLayout()呢?
requestLayout()做所有forceLayout()也做的事情。
forceLayout有道理的。因此,最后它的命名和记录都非常糟糕。
invalidate()---> onDraw()来自UI线程
postInvalidate()---> onDraw()来自后台线程
requestLayout()---> onMeasure()和onLayout()AND 不一定 onDraw()
forceLayout()---> onMeasure()和onLayout() JUST如果直接父级调用requestLayout()。