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 search = _scrollStepSearch(
rootElement,
scrollableKey: scrollableKey,
targetLocator: targetLocator,
scrollableLocator: scrollableLocator,
);
if (search.earlyResult case final CockpitScrollStepResult earlyResult) {
return earlyResult;
}
final targetElement = search.targetElement;
final selection = search.selection!;
final scrollable = selection.candidate;
final position = scrollable.state.position;
var scrollResult = await _scrollScrollableByViewport(
scrollable,
scrollableRegistryTarget: search.registryTarget,
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,
scrollableRegistryTarget: search.registryTarget,
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);
// The pre-scroll resolution stays authoritative while its element remains
// mounted; the full-tree re-probe only runs when the scroll actually
// evicted the resolved element (lazy list rebuild).
final resolvedTarget = targetLocator == null
? targetElement
: targetElement != null && targetElement.mounted
? targetElement
: _findResolvedElementForLocator(rootElement, targetLocator);
final targetVisible =
resolvedTarget != null && _elementIsFullyVisible(resolvedTarget);
return _withScrollableSelection(
scrollResult,
selection,
targetLocator: targetLocator,
targetMounted: resolvedTarget != null,
targetVisible: targetVisible,
);
}