move method
override
Move the given child
in the child list to be after another child.
More efficient than removing and re-adding the child. Requires the child
to already be in the child list at some position. Pass null for after
to
move the child to the start of the child list.
Implementation
@override
void move(RenderBox child, { RenderBox? after }) {
// There are two scenarios:
//
// 1. The child is not keptAlive.
// The child is in the childList maintained by ContainerRenderObjectMixin.
// We can call super.move and update parentData with the new slot.
//
// 2. The child is keptAlive.
// In this case, the child is no longer in the childList but might be stored in
// [_keepAliveBucket]. We need to update the location of the child in the bucket.
final SliverMultiBoxAdaptorParentData childParentData = child.parentData! as SliverMultiBoxAdaptorParentData;
if (!childParentData.keptAlive) {
super.move(child, after: after);
childManager.didAdoptChild(child); // updates the slot in the parentData
// Its slot may change even if super.move does not change the position.
// In this case, we still want to mark as needs layout.
markNeedsLayout();
} else {
// If the child in the bucket is not current child, that means someone has
// already moved and replaced current child, and we cannot remove this child.
if (_keepAliveBucket[childParentData.index] == child) {
_keepAliveBucket.remove(childParentData.index);
}
assert(() {
_debugDanglingKeepAlives.remove(child);
return true;
}());
// Update the slot and reinsert back to _keepAliveBucket in the new slot.
childManager.didAdoptChild(child);
// If there is an existing child in the new slot, that mean that child will
// be moved to other index. In other cases, the existing child should have been
// removed by updateChild. Thus, it is ok to overwrite it.
assert(() {
if (_keepAliveBucket.containsKey(childParentData.index)) {
_debugDanglingKeepAlives.add(_keepAliveBucket[childParentData.index]!);
}
return true;
}());
_keepAliveBucket[childParentData.index!] = child;
}
}