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: [],
displayingChildModelMap: {},
);
}
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;
// Whether the first child being displayed is not found.
bool isNotFound = false;
// 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) {
isNotFound = true;
break;
}
targetFirstChild = nextChild;
}
// The first child being displayed is not found, indicating that the
// ScrollView is not visible.
if (isNotFound) {
return GridViewObserveModel(
sliverGrid: _obj,
viewport: viewport,
visible: false,
firstGroupChildList: [],
displayingChildModelList: [],
displayingChildModelMap: {},
);
}
if (targetFirstChild is! RenderIndexedSemantics) return null;
lastFirstGroupChildWidget = targetFirstChild;
final firstDisplayingChildIndex = targetFirstChild.index;
final firstModel = GridViewObserveDisplayingChildModel(
sliverGrid: _obj,
viewport: viewport,
index: firstDisplayingChildIndex,
renderObject: targetFirstChild,
);
Map<int, GridViewObserveDisplayingChildModel> displayingChildModelMap = {
firstDisplayingChildIndex: firstModel,
};
List<GridViewObserveDisplayingChildModel> firstGroupChildModelList = [
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;
final targetChildIndex = targetChild.index;
final displayingChildModel = GridViewObserveDisplayingChildModel(
sliverGrid: _obj,
viewport: viewport,
index: targetChildIndex,
renderObject: targetChild,
);
firstGroupChildModelList.add(displayingChildModel);
displayingChildModelMap[targetChildIndex] = displayingChildModel;
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;
}
final displayingChildIndex = displayingChild.index;
final displayingChildModel = GridViewObserveDisplayingChildModel(
sliverGrid: _obj,
viewport: viewport,
index: displayingChildIndex,
renderObject: displayingChild,
);
showingChildModelList.add(displayingChildModel);
displayingChildModelMap[displayingChildIndex] = displayingChildModel;
}
displayingChild = _obj.childAfter(displayingChild);
}
return GridViewObserveModel(
sliverGrid: _obj,
viewport: viewport,
visible: true,
firstGroupChildList: firstGroupChildModelList,
displayingChildModelList: showingChildModelList,
displayingChildModelMap: displayingChildModelMap,
);
}