handleGridObserve static method
GridViewObserveModel?
handleGridObserve({
- required BuildContext context,
- double fetchLeadingOffset()?,
- double? customOverlap()?,
- double toNextOverPercent = 1,
Handles observation logic of a sliver similar to SliverGrid.
Implementation
static GridViewObserveModel? handleGridObserve({
required BuildContext context,
double Function()? fetchLeadingOffset,
double? Function(BuildContext)? customOverlap,
double toNextOverPercent = 1,
}) {
final _obj = ObserverUtils.findRenderObject(context);
if (_obj is! RenderSliverMultiBoxAdaptor) return null;
final viewport = ObserverUtils.findViewport(_obj);
if (viewport == null) return null;
if (kDebugMode) {
if (viewport.debugNeedsPaint) return null;
}
// The geometry.visible is not absolutely reliable.
if (!(_obj.geometry?.visible ?? false) ||
_obj.constraints.remainingPaintExtent < 1e-10) {
return GridViewObserveModel(
sliverGrid: _obj,
viewport: viewport,
visible: false,
firstGroupChildList: [],
displayingChildModelList: [],
);
}
final scrollDirection = _obj.constraints.axis;
var firstChild = _obj.firstChild;
if (firstChild == null) return null;
final offset = fetchLeadingOffset?.call() ?? 0;
final overlap = customOverlap?.call(context) ?? _obj.constraints.overlap;
final rawScrollViewOffset = _obj.constraints.scrollOffset + overlap;
var scrollViewOffset = rawScrollViewOffset + offset;
// Find out the first child which is displaying
var targetFirstChild = firstChild;
var lastFirstGroupChildWidget = targetFirstChild;
while (!ObserverUtils.isBelowOffsetWidgetInSliver(
scrollViewOffset: scrollViewOffset,
scrollDirection: scrollDirection,
targetChild: targetFirstChild,
toNextOverPercent: toNextOverPercent,
)) {
/// Entering here means it is not the target object
RenderBox? nextChild = _obj.childAfter(targetFirstChild);
if (nextChild == null) break;
targetFirstChild = nextChild;
}
if (targetFirstChild is! RenderIndexedSemantics) return null;
lastFirstGroupChildWidget = targetFirstChild;
final firstModel = GridViewObserveDisplayingChildModel(
sliverGrid: _obj,
viewport: viewport,
index: targetFirstChild.index,
renderObject: targetFirstChild,
);
List<GridViewObserveDisplayingChildModel> firstGroupChildModelList = [];
firstGroupChildModelList.add(firstModel);
final showingChildrenMaxOffset =
rawScrollViewOffset + _obj.constraints.remainingPaintExtent - overlap;
// Find out other child those have reached the specified offset.
RenderBox? targetChild = _obj.childAfter(targetFirstChild);
while (targetChild != null) {
if (ObserverUtils.isReachOffsetWidgetInSliver(
scrollViewOffset: max(scrollViewOffset, firstModel.layoutOffset),
scrollDirection: scrollDirection,
targetChild: targetChild,
toNextOverPercent: toNextOverPercent,
)) {
if (targetChild is! RenderIndexedSemantics) break;
firstGroupChildModelList.add(GridViewObserveDisplayingChildModel(
sliverGrid: _obj,
viewport: viewport,
index: targetChild.index,
renderObject: targetChild,
));
lastFirstGroupChildWidget = targetChild;
}
RenderBox? nextChild = _obj.childAfter(targetChild);
if (nextChild == null) break;
targetChild = nextChild;
}
List<GridViewObserveDisplayingChildModel> showingChildModelList =
List.from(firstGroupChildModelList);
// Find the remaining children that are being displayed
var displayingChild = _obj.childAfter(lastFirstGroupChildWidget);
while (displayingChild != null) {
if (ObserverUtils.isDisplayingChildInSliver(
targetChild: displayingChild,
showingChildrenMaxOffset: showingChildrenMaxOffset,
scrollViewOffset: scrollViewOffset,
scrollDirection: scrollDirection,
toNextOverPercent: toNextOverPercent,
)) {
if (displayingChild is! RenderIndexedSemantics) {
continue;
}
showingChildModelList.add(GridViewObserveDisplayingChildModel(
sliverGrid: _obj,
viewport: viewport,
index: displayingChild.index,
renderObject: displayingChild,
));
}
displayingChild = _obj.childAfter(displayingChild);
}
return GridViewObserveModel(
sliverGrid: _obj,
viewport: viewport,
visible: true,
firstGroupChildList: firstGroupChildModelList,
displayingChildModelList: showingChildModelList,
);
}