performRebuild method

  1. @override
void performRebuild ()
override

Copied and adapted from SliverMultiBoxAdaptorElement.performRebuild. In addition:

Calls the AnimatedRenderSliverList.didChangeDependencies method if a dependency has been changed.

Apply all build updates _BuildUpdate of the list before calling the original method implementation.

Implementation

@override
void performRebuild() {
  //""""""""""""""""""""""""""""""""""""""""""""""""""""""
  if (_didChangeDependencies) {
    renderObject.didChangeDependencies(this);
    _didChangeDependencies = false;
  }
  super.performRebuild();
  for (final upd in _updates) {
    switch (upd.type) {
      case _BuildUpdateType.NEW_REMOVING_INTERVAL:
        _updateOnNewRemovingInterval(upd);
        break;
      case _BuildUpdateType.NEW_RESIZING_INTERVAL:
        _updateOnNewResizingInterval(upd);
        break;
      case _BuildUpdateType.REMOVED_TO_RESIZING:
        _updateOnIntervalRemovedToResizing(upd);
        break;
      case _BuildUpdateType.RESIZED_TO_INSERTING:
        _updateOnIntervalResizedToInserting(upd);
        break;
      case _BuildUpdateType.RESIZED_TO_DISPOSING:
        _updateOnIntervalResizedToDisposing(upd);
        break;
      // case _BuildUpdateType.INSERTED_TO_DISPOSING:
      //   _updateOnIntervalInsertedToDisposing(upd);
      //   break;
    }
  }
  _updates.clear();
  _currentlyUpdatingChildIndex = null;
  //""""""""""""""""""""""""""""""""""""""""""""""""""""""
  _currentBeforeChild = null;
  assert(_currentlyUpdatingChildIndex == null);
  try {
    final newChildren = SplayTreeMap<int, Element>();
    final Map<int, double> indexToLayoutOffset = HashMap<int, double>();

    for (final index in _childElements.keys.toList()) {
      assert(_childElements[index] != null);
      final key = _childElements[index].widget.key;
      var newIndex = key == null ? null : widget.delegate.findIndexByKey(key);

      final childParentData = _childElements[index].renderObject?.parentData
          as SliverMultiBoxAdaptorParentData;

      if (childParentData != null && childParentData.layoutOffset != null) {
        indexToLayoutOffset[index] = childParentData.layoutOffset;
      }

      if (newIndex != null && newIndex != index) {
        // The layout offset of the child being moved is no longer accurate.
        if (childParentData != null) childParentData.layoutOffset = null;

        newChildren[newIndex] = _childElements[index];
        // We need to make sure the original index gets processed.
        newChildren.putIfAbsent(index, () => null);
        // We do not want the remapped child to get deactivated during processElement.
        _childElements.remove(index);
      } else {
        newChildren.putIfAbsent(index, () => _childElements[index]);
      }
    }

    void processElement(int index) {
      _currentlyUpdatingChildIndex = index;
      if (_childElements[index] != null &&
          _childElements[index] != newChildren[index]) {
        // This index has an old child that isn't used anywhere and should be deactivated.
        _childElements[index] =
            updateChild(_childElements[index], null, index);
      }
      final newChild = updateChild(newChildren[index], _build(index), index);
      if (newChild != null) {
        _childElements[index] = newChild;
        final parentData = newChild.renderObject.parentData
            as SliverMultiBoxAdaptorParentData;
        if (index == 0) {
          parentData.layoutOffset = 0.0;
        } else if (indexToLayoutOffset.containsKey(index)) {
          parentData.layoutOffset = indexToLayoutOffset[index];
        }
        if (!parentData.keptAlive) {
          _currentBeforeChild = newChild.renderObject as RenderBox;
        }
      } else {
        _childElements.remove(index);
      }
    } // processElement

    // Moving children will temporary violate the integrity.
    renderObject.debugChildIntegrityEnabled = false;

    newChildren.keys.forEach(processElement); // !!

    if (_didUnderflow) {
      final lastKey = _childElements.lastKey() ?? -1;
      final rightBoundary = lastKey + 1;
      newChildren[rightBoundary] = _childElements[rightBoundary];
      processElement(rightBoundary);
    }
  } finally {
    _currentlyUpdatingChildIndex = null;
    renderObject.debugChildIntegrityEnabled = true;
  }
}