Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/209.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android forceLayout()、requestLayout()和invalidate()的用法_Android_Android Layout_Android View - Fatal编程技术网

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();