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 scrollables = _discoverScrollables(rootContext as Element)
.where((candidate) {
final position = candidate.state.position;
if (!position.haveDimensions || position.maxScrollExtent <= 0) {
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 scrollable = _selectScrollableCandidate(
scrollables,
targetLocator: targetLocator,
scrollableLocator: scrollableLocator,
);
if (scrollable == null) {
return const CockpitScrollStepResult(didScroll: false);
}
final position = scrollable.state.position;
final probeSegmentCount = probeDuringScroll
? _scrollProbeSegmentCount(
targetLocator: targetLocator,
viewportFraction: viewportFraction,
)
: 1;
if (probeSegmentCount > 1) {
final stepViewportFraction = viewportFraction / probeSegmentCount;
final stepDuration = duration == Duration.zero
? Duration.zero
: Duration(
milliseconds: (duration.inMilliseconds / probeSegmentCount)
.ceil()
.clamp(1, duration.inMilliseconds),
);
final pixelsBeforeProbe = position.pixels;
var didScroll = false;
CockpitScrollStepResult? lastStep;
for (var index = 0; index < probeSegmentCount; index += 1) {
final stepResult = await _scrollScrollableByViewport(
scrollable,
reverse: reverse,
viewportFraction: stepViewportFraction,
duration: stepDuration,
gestureProfile: gestureProfile,
continuous: continuous,
postScrollEnsureVisible: postScrollEnsureVisible,
preferProgrammatic: true,
);
lastStep = stepResult;
didScroll = didScroll || stepResult.didScroll;
if (_locatorIsVisible(targetLocator)) {
return _mergeProbeResult(
base: stepResult,
pixelsBefore: pixelsBeforeProbe,
pixelsAfter: position.pixels,
didScroll: didScroll,
);
}
if (!stepResult.didScroll) {
break;
}
}
if (lastStep != null) {
return _mergeProbeResult(
base: lastStep,
pixelsBefore: pixelsBeforeProbe,
pixelsAfter: position.pixels,
didScroll: didScroll,
);
}
}
return _scrollScrollableByViewport(
scrollable,
reverse: reverse,
viewportFraction: viewportFraction,
duration: duration,
gestureProfile: gestureProfile,
continuous: continuous,
postScrollEnsureVisible: postScrollEnsureVisible,
);
}