estimateLayoutOffset method
_Measure
estimateLayoutOffset()
override
Implementation
@override
_Measure estimateLayoutOffset(int buildIndex, int childCount, double? time,
_MovingPopUpList? popUpList) {
assert(!intervalManager.hasPendingUpdates);
assert(buildIndex >= 0 && buildIndex <= childCount);
final list = listOf(popUpList)!;
late int firstBuildIndex, lastBuildIndex /* exclueded */;
late double size, scrollOffset;
late int count, offset;
late _Measure value;
Iterable<_Interval>? ilist;
var outside = false;
if (buildIndex == 0) {
value = _Measure.zero;
time = null;
} else if (buildIndex == childCount && popUpList == null) {
value = _Measure(geometry!.scrollExtent);
} else if (buildIndex < indexOf(list.firstChild!)) {
// above
final pd = parentDataOf(list.firstChild!)!;
firstBuildIndex = 0;
lastBuildIndex = pd.index!;
scrollOffset = 0.0;
size = pd.layoutOffset!;
count = lastBuildIndex;
offset = buildIndex;
outside = true;
} else if (buildIndex > indexOf(list.lastChild!)) {
// bottom
final lastParentData = parentDataOf(list.lastChild!)!;
firstBuildIndex = lastParentData.index! + 1;
scrollOffset =
lastParentData.layoutOffset! + paintExtentOf(list.lastChild!);
if (childCount == firstBuildIndex) {
value = _Measure(scrollOffset);
} else {
lastBuildIndex = childCount;
if (popUpList == null) {
size = geometry!.scrollExtent - scrollOffset;
} else {
final firstParentData = parentDataOf(list.firstChild!)!;
// For popups you can only estimate the size
size = extrapolateMaxScrollOffset(
popUpList,
firstParentData.index!,
lastParentData.index!,
firstParentData.layoutOffset!,
scrollOffset,
childCount) -
scrollOffset;
}
count = childCount - firstBuildIndex;
offset = buildIndex - firstBuildIndex;
outside = true;
}
} else {
// inner
var child = list.firstChild;
while (child != null) {
if (indexOf(child) == buildIndex) {
value = parentDataOf(child)!.layoutOffset!.toExactMeasure();
break;
}
child = childAfter(child);
}
assert(child != null);
}
if (outside) {
ilist ??=
(popUpList == null) ? intervalManager.list : popUpList.intervals;
for (final i in ilist.expandedIntervals.whereType<_SpaceInterval>()) {
final bi = i.actualBuildOffset;
if (bi >= firstBuildIndex) {
if (bi >= lastBuildIndex) break;
final csz = i.currentSize;
if (bi < buildIndex) {
scrollOffset += csz;
offset--;
}
count--;
size -= csz;
}
}
if (size < 0) size = 0;
if (count > 0) scrollOffset += (offset * size) / count;
value = _Measure(scrollOffset, true);
}
if (time != null) {
var bi = 0, adjust = 0.0;
ilist ??=
(popUpList == null) ? intervalManager.list : popUpList.intervals;
for (final i in ilist) {
if (bi >= buildIndex) break;
if (i is _AnimatedSpaceInterval) {
adjust += i.futureSize(time) - i.currentSize;
}
bi += i.buildCount;
}
value += adjust.toExactMeasure();
}
if (popUpList != null) value += _Measure(popUpList.currentScrollOffset!);
assert(value.value.isFinite);
return value;
}