Android forceLayout()、requestLayout()和invalidate()的用法
我对Android forceLayout()、requestLayout()和invalidate()的用法,android,android-layout,android-view,Android,Android Layout,Android View,我对View类的forceLayout()、requestLayout()和invalidate()方法的角色有点困惑 什么时候叫他们?在这里你可以找到一些回应: 对我来说,调用invalidate()仅刷新视图,调用requestLayout()刷新视图并计算屏幕上视图的大小 对要重画的视图使用invalidate(),它将调用其onDraw(Canvas c),requestLayout()将使整个布局渲染(测量阶段和定位阶段)再次运行。如果您在运行时更改子视图的大小,但仅在特定情况下(例
View
类的forceLayout()
、requestLayout()
和invalidate()
方法的角色有点困惑
什么时候叫他们?在这里你可以找到一些回应:
对我来说,调用
invalidate()
仅刷新视图,调用requestLayout()
刷新视图并计算屏幕上视图的大小 对要重画的视图使用invalidate(),它将调用其onDraw(Canvas c),requestLayout()将使整个布局渲染(测量阶段和定位阶段)再次运行。如果您在运行时更改子视图的大小,但仅在特定情况下(例如来自父视图的约束)才应该使用它(我的意思是父视图的高度或宽度是包裹内容,因此在子视图可以再次包裹之前匹配测量子视图)为了更好地理解由提供的答案,我建议您通过以下方式查看此很棒的视图生命周期图:
当您要计划视图的重画时,调用invalidate()
。它最终将导致调用onDraw
(很快,但不是立即)。自定义视图何时调用它的一个示例是文本或背景颜色属性发生更改时
将重新绘制视图,但大小不会更改
如果视图的某些更改会影响大小,则应调用requestLayout()
。这将触发测量时的onMeasure
和onLayout
,不仅适用于此视图,而且适用于父视图
调用requestLayout()
是错误的(与接受答案中的图表所暗示的相反),因此它通常与invalidate()
结合使用
例如,当自定义标签的文本属性发生更改时。标签会改变大小,因此需要重新测量和绘制
如果父视图组上调用了requestLayout()
,则无需重新测量和重新布置其子视图。但是,如果重新测量和重新调整中应包括一个子项,则可以对该子项调用forceLayout()
forceLayout()
仅在子级与直接父级上的requestLayout()
一起出现时才对其有效。单独调用forceLayout()
将无效,因为它不会触发视图树上的requestLayout()
有关forceLayout()
的详细说明,请阅读
进一步研究
- (有用的文档)
forceLayout()
不正确
如您所见,它只是将视图标记为“需要重新部署”,但它既不计划也不触发重新部署。在将来某个时候,视图的父视图由于其他原因被放置之前,不会进行重新显示
使用forceLayout()
和requestLayout()
时还有一个更大的问题:
假设您在视图上调用了forceLayout()
。现在,当对该视图的后代调用requestLayout()
时,Android将递归地调用该后代的祖先的requestLayout()
。问题是,它将在调用了forceLayout()
的视图上停止递归因此,requestLayout()
调用永远不会到达视图根目录,因此永远不会安排布局过程。视图层次结构的整个子树正在等待布局,对该子树的任何视图调用requestLayout()
都不会导致布局。只有在该子树之外的任何视图上调用requestLayout()
,才能解除此咒语
>我考虑执行<代码> FracelayOut.()/Cux>(以及它如何影响<代码> RealStestOutAuter)(/Cule>),并且不应该在代码中使用该函数。
postInvalidate()
-->onDraw()
来自后台线程
requestLayout()
-->onMeasure()
和onLayout()
和不一定onDraw()
- 重要:调用此方法不会影响被调用类的子类
forceLayout()
-->onMeasure()
和onLayout()
如果直接父级调用requestLayout()
forceLayout()如何那么?@fiddler,这个方法只设置了两个标志:PFLAG\u FORCE\u布局和PFLAG_INVALIDATED@suitianshi设置标志的结果是什么?@Sergey结果似乎是该标志覆盖了度量缓存(视图使用缓存在将来对同一度量进行更快的度量);参见View.java的第18783行:我经常看到在调用invalidate之后直接调用requestLayout,我甚至看到在Android源代码中发生了类似TextView的事情,但根据这个图,这样做是多余的,对吗?那么这样做有什么目的吗?这是一个有趣的问题,老实说,我不知道我很清楚他们为什么在TextView
中调用这两个方法。我想他们可能想在更改布局相关参数之前最后一次绘制视图,但如果我们考虑以不同的顺序调用这些调用(他们调用invalidate()
就在TextView
中的requestLayout()
之后。也许它值得再问一个关于StackOverflow的问题:)?(1/2):我认为你不太理解这两种方法(invalidate()
和requestLayout()
)。这些方法的目的是告诉视图
invalidate();
requestLayout();