forceLayout(),requestLayout()和invalidate()的用法

时间:2012-12-13 08:55:06

标签: android android-layout android-view

我对forceLayout()类的requestLayout()invalidate()View方法的作用感到有点困惑。

他们何时被召唤?

6 个答案:

答案 0 :(得分:309)

为了更好地理解François BOURLIEUXDalvik提供的答案,我建议您按Arpit Mathur查看这个令人敬畏的视图生命周期图: enter image description here

答案 1 :(得分:97)

invalidate()

如果要安排重绘视图,则会调用invalidate()。这将导致onDraw最终被调用(很快,但不是立即)。自定义视图调用它的示例是文本或背景颜色属性发生更改时。

视图将被重绘,但大小不会改变。

requestLayout()

如果您的观看内容发生变化会影响尺寸,则应致电requestLayout()。这将不仅会触发此视图的onMeasureonLayout,还会触发父视图的整个行。

调用requestLayout()not guaranteed to result in an onDraw(与接受的答案中的图表相反),因此通常与invalidate()结合使用。

invalidate();
requestLayout();

此示例是自定义标签的文本属性已更改。标签会改变尺寸,因此需要重新测量和重新绘制。

forceLayout()

如果在父视图组上调用requestLayout(),则无需重新测量并重新布局其子视图。但是,如果孩子应该被包括在重新测量和重新布局中,那么您可以给孩子打电话forceLayout()forceLayout()仅适用于与其直接父级requestLayout()一起发生的子项。单独调用forceLayout()将不起作用,因为它不会触发视图树requestLayout()

阅读this Q&A,了解forceLayout()的详细说明。

进一步研究

答案 2 :(得分:25)

在这里您可以找到一些回复: http://developer.android.com/guide/topics/ui/how-android-draws.html

对我来说,对invalidate()的调用只会刷新视图,并且对requestLayout()的调用会刷新视图并计算屏幕上视图的大小。

答案 3 :(得分:3)

您在要重绘的视图上使用invalidate(),它将调用onDraw(Canvas c),而requestLayout()将使整个布局渲染(测量阶段和定位阶段)再次运行。如果要在运行时更改子视图的大小,则应该使用它,但仅在特殊情况下(如父视图中的约束)(我的意思是父高度或宽度为WRAP_CONTENT,因此匹配测量子项,然后再将它们包装起来)

答案 4 :(得分:3)

关于forceLayout()

This answer不正确。

正如您在the code of forceLayout()中所看到的那样,它只是将视图标记为"需要重新布局"但它既不安排也不触发重新布局。重播将不会发生,直到将来某个时候,观点的父母出于其他原因进行了布局。

使用forceLayout()requestLayout()时,还有一个更大的问题:

我们假设您已在视图中调用forceLayout()。现在,当在该视图的后代上调用requestLayout()时,Android将递归调用该后代的祖先上的requestLayout()。问题是它会在你称之为forceLayout()的视图上停止递归。 因此requestLayout()调用永远不会到达视图根目录,因此从不安排布局传递。视图层次结构的整个子树正在等待布局并在任何位置调用requestLayout()该子树的视图不会导致布局。只在该子树外的任何视图上调用requestLayout()都会破坏该法术。

我考虑forceLayout()的实施(以及它如何影响requestLayout(),你不应该在你的代码中使用该功能。

答案 5 :(得分:2)

invalidate() ---> onDraw()来自UI线程

postInvalidate() ---> onDraw()来自后台线程

requestLayout() ---> onMeasure()onLayout()并且不必 onDraw()

  • 重要:调用此方法不会影响被调用类的子级。

forceLayout() ---> onMeasure()onLayout() 只要直接父节点名为requestLayout()