flutter KeepAlive

KeepAlive.png

KeepAlive

KeepAlive通过设置parentData(KeepAliveParentDataMixin类型)的keepAlive参数,控制RenderSliverMultiBoxAdaptor中_keepAliveBucket存储child RenderBox。

//用于SliverWithKeepAliveWidget类型小部件,比如SliverGrid、SliverList
class KeepAlive extends ParentDataWidget 

class SliverMultiBoxAdaptorParentData extends SliverLogicalParentData with ContainerParentDataMixin, KeepAliveParentDataMixin

class RenderSliverMultiBoxAdaptor

void _createOrObtainChild(int index, { RenderBox after }) {
    invokeLayoutCallback((SliverConstraints constraints) {
      assert(constraints == this.constraints);
      if (_keepAliveBucket.containsKey(index)) {
        final RenderBox child = _keepAliveBucket.remove(index);
        final SliverMultiBoxAdaptorParentData childParentData = child.parentData;
        assert(childParentData._keptAlive);
        dropChild(child);
        child.parentData = childParentData;
        insert(child, after: after);
        childParentData._keptAlive = false;
      } else {
        _childManager.createChild(index, after: after);
      }
    });
  }

void _destroyOrCacheChild(RenderBox child) {
    final SliverMultiBoxAdaptorParentData childParentData = child.parentData;
    if (childParentData.keepAlive) {
      assert(!childParentData._keptAlive);
      remove(child);
      _keepAliveBucket[childParentData.index] = child;
      child.parentData = childParentData;
      super.adoptChild(child);
      childParentData._keptAlive = true;
    } else {
      assert(child.parent == this);
      _childManager.removeChild(child);
      assert(child.parent == null);
    }
  }

AutomaticKeepAlive

通过监听KeepAliveNotification设置_keepingAlive参数,从而设置build的时候KeepAlive的keepAlive参数

AutomaticKeepAliveClientMixin

要和AutomaticKeepAlive配合使用,像PageView等的小部件会自动给其child嵌套AutomaticKeepAlive,此时如果child混合AutomaticKeepAliveClientMixin,则可以通过AutomaticKeepAliveClientMixin发送KeepAliveNotification通知实现keepAlive效果

mixin AutomaticKeepAliveClientMixin on State {
  KeepAliveHandle _keepAliveHandle;

  void _ensureKeepAlive() {
    assert(_keepAliveHandle == null);
    _keepAliveHandle = KeepAliveHandle();
    KeepAliveNotification(_keepAliveHandle).dispatch(context);
  }

  @protected
  bool get wantKeepAlive;

  @protected
  void updateKeepAlive() {
    if (wantKeepAlive) {
      if (_keepAliveHandle == null)
        _ensureKeepAlive();
    } else {
      if (_keepAliveHandle != null)
        _releaseKeepAlive();
    }
  }

  @override
  void initState() {
    super.initState();
    if (wantKeepAlive)
      _ensureKeepAlive();
  }

你可能感兴趣的:(flutter KeepAlive)