performRebuild method
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;
}
}