我对视图类的forceLayout(), requestLayout()和invalidate()方法的角色有点困惑。

什么时候叫他们?


当前回答

invalidate()——> onDraw()从UI线程

postInvalidate()——> onDraw()从后台线程

requestLayout()——> onMeasure() and onLayout() and NOT Necessarily onDraw()

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

forceLayout()——> onMeasure()和onLayout()只是如果直接父调用requestLayout()。

其他回答

为了更好地理解François BOURLIEUX和Dalvik提供的答案,我建议你看看Arpit Mathur的这张很棒的视图生命周期图:

invalidate()——> onDraw()从UI线程

postInvalidate()——> onDraw()从后台线程

requestLayout()——> onMeasure() and onLayout() and NOT Necessarily onDraw()

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

forceLayout()——> onMeasure()和onLayout()只是如果直接父调用requestLayout()。

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

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

你在你想要重绘的视图上使用invalidate(),它将使它的onDraw(Canvas c)被调用,requestLayout()将使整个布局渲染(测量阶段和定位阶段)再次运行。如果你在运行时改变子视图的大小,你应该使用它,但只有在特定的情况下,比如来自父视图的约束(我的意思是父视图的高度或宽度是WRAP_CONTENT,所以匹配测量子视图之前,他们可以再次包装他们)

无效()

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

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

请求布局()

如果视图的某些变化将影响大小,则应该调用requestLayout()。这将触发onMeasure和onLayout,不仅为这个视图,而且为父视图的所有方式。

调用requestLayout()并不保证会导致onDraw(与已接受答案中的图表所暗示的相反),因此它通常与invalidate()结合使用。

invalidate();
requestLayout();

这方面的一个例子是自定义标签的文本属性被更改。标签会改变大小,因此需要重新测量和绘制。

forceLayout ()

当父视图组上调用requestLayout()时,它不需要重新测量和重新布局它的子视图。但是,如果要在重测量和重新布局中包含子元素,那么可以在子元素上调用forceLayout()。forceLayout()只有在子节点上与直接父节点上的requestLayout()一起发生时才有效。单独调用forceLayout()将没有任何效果,因为它不会触发视图树上方的requestLayout()。

阅读此问答以获得forceLayout()的更详细描述。

进一步的研究

创建视图类:添加属性和事件(有用的文档) 查看文档 查看源代码