scrollByViewport method
Future<CockpitScrollStepResult>
scrollByViewport({
- bool reverse = false,
- double viewportFraction = 0.8,
- String? scrollableKey,
- CockpitLocator? targetLocator,
- CockpitLocator? scrollableLocator,
- Duration duration = const Duration(milliseconds: 220),
- CockpitGestureProfile gestureProfile = CockpitGestureProfile.userLike,
- bool continuous = false,
- bool postScrollEnsureVisible = true,
- bool probeDuringScroll = true,
Implementation
Future<CockpitScrollStepResult> scrollByViewport({
bool reverse = false,
double viewportFraction = 0.8,
String? scrollableKey,
CockpitLocator? targetLocator,
CockpitLocator? scrollableLocator,
Duration duration = const Duration(milliseconds: 220),
CockpitGestureProfile gestureProfile = CockpitGestureProfile.userLike,
bool continuous = false,
bool postScrollEnsureVisible = true,
bool probeDuringScroll = true,
}) async {
final rootContext = _boundaryKey.currentContext;
if (rootContext == null) {
return const CockpitScrollStepResult(didScroll: false);
}
final rootElement = rootContext as Element;
final targetElement = targetLocator == null
? null
: _findResolvedElementForLocator(rootElement, targetLocator);
final scrollables =
_scrollableCandidatesForSearch(
rootElement,
targetLocator: targetLocator,
targetElement: targetElement,
)
.where((candidate) {
final position = candidate.state.position;
if (!position.haveDimensions || position.maxScrollExtent <= 0) {
return false;
}
if (targetLocator != null &&
!position.physics.allowUserScrolling) {
return false;
}
if (scrollableKey == null || scrollableKey.isEmpty) {
return true;
}
return candidate.keyValue == scrollableKey;
})
.toList(growable: false);
if (scrollables.isEmpty) {
return const CockpitScrollStepResult(didScroll: false);
}
final selection = _selectScrollableCandidate(
scrollables,
targetLocator: targetLocator,
targetElement: targetElement,
scrollableLocator: scrollableLocator,
);
if (selection == null) {
final targetMounted = targetElement != null;
return CockpitScrollStepResult(
didScroll: false,
scrollableCandidateCount: scrollables.length,
targetVisibilityObserved: targetLocator != null,
targetMounted: targetMounted,
targetVisible: targetMounted && _locatorIsVisible(targetLocator),
);
}
final scrollable = selection.candidate;
final position = scrollable.state.position;
final targetAlreadyVisible = targetLocator?.kind == CockpitLocatorKind.route
? widget.routeName == targetLocator?.value
: targetElement != null && _elementIsFullyVisible(targetElement);
if (targetAlreadyVisible) {
return _withScrollableSelection(
CockpitScrollStepResult(
didScroll: false,
strategy: 'alreadyVisible',
scrollableKey: scrollable.keyValue,
scrollablePath: scrollable.path,
scrollableTypeName: scrollable.typeName,
pixelsBefore: position.pixels,
pixelsAfter: position.pixels,
nextPixels: position.pixels,
minScrollExtent: position.minScrollExtent,
maxScrollExtent: position.maxScrollExtent,
viewportDimension: position.viewportDimension,
acceptsUserOffset: position.physics.shouldAcceptUserOffset(position),
allowsProgrammaticScroll: position.physics.allowUserScrolling,
targetMounted: true,
targetVisible: true,
),
selection,
targetLocator: targetLocator,
targetMounted: targetElement != null,
);
}
var scrollResult = await _scrollScrollableByViewport(
scrollable,
reverse: reverse,
viewportFraction: viewportFraction,
duration: duration,
gestureProfile: gestureProfile,
continuous: continuous,
postScrollEnsureVisible: postScrollEnsureVisible,
preferProgrammatic: probeDuringScroll && targetLocator != null,
);
if (probeDuringScroll && targetLocator != null) {
await _settleAtomicRevealFrame();
}
if (!scrollResult.didScroll &&
_scrollExtentExpanded(scrollResult, position, reverse: reverse)) {
final expandedResult = await _scrollScrollableByViewport(
scrollable,
reverse: reverse,
viewportFraction: viewportFraction,
duration: duration,
gestureProfile: gestureProfile,
continuous: continuous,
postScrollEnsureVisible: postScrollEnsureVisible,
preferProgrammatic: probeDuringScroll && targetLocator != null,
);
scrollResult = _mergeExpandedScrollStep(scrollResult, expandedResult);
if (probeDuringScroll && targetLocator != null) {
await _settleAtomicRevealFrame();
}
}
scrollResult = _refreshScrollExtents(scrollResult, position);
final resolvedTarget = targetLocator == null
? targetElement
: _findResolvedElementForLocator(rootElement, targetLocator);
final targetVisible =
resolvedTarget != null && _elementIsFullyVisible(resolvedTarget);
return _withScrollableSelection(
scrollResult,
selection,
targetLocator: targetLocator,
targetMounted: resolvedTarget != null,
targetVisible: targetVisible,
);
}