scrollUntilVisible method
- SerializableFinder scrollable,
- SerializableFinder item, {
- double alignment = 0.0,
- double dxScroll = 0.0,
- double dyScroll = 0.0,
- Duration? timeout,
Repeatedly scroll the widget located by scrollable by dxScroll and
dyScroll until item is visible, and then use scrollIntoView to
ensure the item's final position matches alignment.
The scrollable must locate the scrolling widget that contains item.
Typically find.byType('ListView') or find.byType('CustomScrollView').
At least one of dxScroll and dyScroll must be non-zero.
If item is below the currently visible items, then specify a negative
value for dyScroll that's a small enough increment to expose item
without potentially scrolling it up and completely out of view. Similarly
if item is above, then specify a positive value for dyScroll.
If item is to the right of the currently visible items, then
specify a negative value for dxScroll that's a small enough increment to
expose item without potentially scrolling it up and completely out of
view. Similarly if item is to the left, then specify a positive value
for dyScroll.
The timeout value should be long enough to accommodate as many scrolls
as needed to bring an item into view. The default is to not time out.
Implementation
Future<void> scrollUntilVisible(
  SerializableFinder scrollable,
  SerializableFinder item, {
  double alignment = 0.0,
  double dxScroll = 0.0,
  double dyScroll = 0.0,
  Duration? timeout,
}) async {
  assert(dxScroll != 0.0 || dyScroll != 0.0);
  // Kick off an (unawaited) waitFor that will complete when the item we're
  // looking for finally scrolls onscreen. We add an initial pause to give it
  // the chance to complete if the item is already onscreen; if not, scroll
  // repeatedly until we either find the item or time out.
  bool isVisible = false;
  waitFor(item, timeout: timeout).then<void>((_) {
    isVisible = true;
  });
  await Future<void>.delayed(const Duration(milliseconds: 500));
  while (!isVisible) {
    await scroll(scrollable, dxScroll, dyScroll, const Duration(milliseconds: 100));
    await Future<void>.delayed(const Duration(milliseconds: 500));
  }
  return scrollIntoView(item, alignment: alignment);
}