返回
揭秘View#requestLayout()的幕后运作:受影响View大起底!
Android
2023-11-15 11:47:51
调用View#requestLayout(),牵一发而动全身
当您调用View#requestLayout()方法时,它会引发一连串的事件,影响到多个View。这些受影响的View包括:
-
发起
requestLayout()
调用的View:- 该View会标记自身为需要重新布局,即设置其
mPrivateFlags
中的PFLAG_FORCE_LAYOUT
标志位。 - 同时,它也会将
PFLAG_FORCE_LAYOUT
标志位传播给它的所有父View ,直至ViewRootImpl
。
- 该View会标记自身为需要重新布局,即设置其
-
各级父View(直到ViewRootImpl):
- 这些父View也会标记自身为需要重新布局,即设置它们的
mPrivateFlags
中的PFLAG_FORCE_LAYOUT
标志位。
- 这些父View也会标记自身为需要重新布局,即设置它们的
-
发起
requestLayout()
调用的View及其所有父View:- 这些View会依次调用它们的
invalidate()
方法,触发重绘。 - 重绘过程会从发起
requestLayout()
调用的View开始,依次向上遍历它的父View,直到ViewRootImpl
。
- 这些View会依次调用它们的
-
发起
requestLayout()
调用的View及其所有父View:- 这些View会依次调用它们的
measure()
方法,触发重新测量。 - 重新测量过程也会从发起
requestLayout()
调用的View开始,依次向上遍历它的父View,直到ViewRootImpl
。
- 这些View会依次调用它们的
-
发起
requestLayout()
调用的View及其所有父View:- 这些View会依次调用它们的
layout()
方法,触发重新布局。 - 重新布局过程也会从发起
requestLayout()
调用的View开始,依次向上遍历它的父View,直到ViewRootImpl
。
- 这些View会依次调用它们的
影响范围的背后逻辑
上述影响范围的背后逻辑在于,View#requestLayout()方法会触发View的重新布局,而重新布局过程需要从发起requestLayout()
调用的View开始,依次向上遍历它的父View,直到ViewRootImpl
。在这个过程中,所有经过的View都会受到影响,包括:
- 需要重新布局的View: 这些View会标记自身为需要重新布局,并依次向上传播
PFLAG_FORCE_LAYOUT
标志位。 - 需要重绘的View: 这些View会调用它们的
invalidate()
方法,触发重绘。 - 需要重新测量的View: 这些View会调用它们的
measure()
方法,触发重新测量。 - 需要重新布局的View: 这些View会调用它们的
layout()
方法,触发重新布局。
优化建议
了解了View#requestLayout()方法的影响范围后,我们就可以针对性地进行优化,以提高布局性能。一些优化建议包括:
- 避免在不需要的时候调用
requestLayout()
方法。 - 尽量减少发起
requestLayout()
调用的View的数量。 - 使用
invalidate()
方法代替requestLayout()
方法,以避免不必要的重新布局。 - 使用
measure()
方法代替requestLayout()
方法,以避免不必要