RepaintBoundary、RelayoutBoundary

RepaintBoundary

实现方式:直接使用RepaintBoundary小部件

  • RepaintBoundary子树repaint的时候,只有RepaintBoundary子树会被repaint,不影响父级和同级的其他子树
  • 如果父widget repaint,则RepaintBoundary子树也会repaint
  • 如果非RepaintBoundary子树repaint,则也会引起父widget repaint,但是同级的RepaintBoundary不会repaint

如下图所示,

  • one或者two repaint的时候只有其自身repaint,不影响bottom和其他同级
  • three repaint的时候,bottom也会repaint,但是one和two不会repaint
  • bottom repaint的时候,one、two、three都会repaint
IMG_1037.PNG

RelayoutBoundary

实现方式:使用Container或者SizedBox,设定固定宽高,因为Container或者SizedBox底下都是用了RenderConstrainedBox(RenderObject类),如果设置了固定宽高,则constraints.isTight为true,从而relayoutBoundary = this

renderObject在layout阶段做了Relayout boundary的优化,当子树进行relayout时,满足下面三种中的一种

  • parentUsesSize == false
  • sizedByParent == true
  • constraints.isTight
    那么该renderObject设置为Relayout boundary,也就是该renderObject的重新layout不触发parent的layout,一般情况下开发人员不需要关心Relayout boundary,除非是使用CustomMultiChildLayout
if (!parentUsesSize || sizedByParent || constraints.isTight || parent is! RenderObject) {
      relayoutBoundary = this;
    } else {
      final RenderObject parent = this.parent;
      relayoutBoundary = parent._relayoutBoundary;
    }
.........
if (_relayoutBoundary != null && relayoutBoundary != _relayoutBoundary) {
      // The local relayout boundary has changed, must notify children in case
      // they also need updating. Otherwise, they will be confused about what
      // their actual relayout boundary is later.
      visitChildren((RenderObject child) {
        child._cleanRelayoutBoundary();
      });
    }
    _relayoutBoundary = relayoutBoundary;
void markNeedsLayout() {
....
    if (_relayoutBoundary != this) {
      markParentNeedsLayout();
    }
....
  }

由以上源码可知,RenderObject中,relayoutBoundary不是自己就是parent。如果是自己,当layout的时候就不会要求parent layout;如果不是自己,当layout的时候就会要求parent layout。

你可能感兴趣的:(RepaintBoundary、RelayoutBoundary)