Future<Null> ensureVisible(BuildContext context, { Duration duration, Curve curve: Curves.ease })

Scrolls the closest enclosing scrollable to make the given context visible.

Source

static Future<Null> ensureVisible(BuildContext context, { Duration duration, Curve curve: Curves.ease }) {
  assert(context.findRenderObject() is RenderBox);
  // TODO(abarth): This function doesn't handle nested scrollable widgets.

  ScrollableState scrollable = Scrollable.of(context);
  if (scrollable == null)
    return new Future<Null>.value();

  RenderBox targetBox = context.findRenderObject();
  assert(targetBox.attached);
  Size targetSize = targetBox.size;

  RenderBox scrollableBox = scrollable.context.findRenderObject();
  assert(scrollableBox.attached);
  Size scrollableSize = scrollableBox.size;

  double targetMin;
  double targetMax;
  double scrollableMin;
  double scrollableMax;

  switch (scrollable.config.scrollDirection) {
    case Axis.vertical:
      targetMin = targetBox.localToGlobal(Point.origin).y;
      targetMax = targetBox.localToGlobal(new Point(0.0, targetSize.height)).y;
      scrollableMin = scrollableBox.localToGlobal(Point.origin).y;
      scrollableMax = scrollableBox.localToGlobal(new Point(0.0, scrollableSize.height)).y;
      break;
    case Axis.horizontal:
      targetMin = targetBox.localToGlobal(Point.origin).x;
      targetMax = targetBox.localToGlobal(new Point(targetSize.width, 0.0)).x;
      scrollableMin = scrollableBox.localToGlobal(Point.origin).x;
      scrollableMax = scrollableBox.localToGlobal(new Point(scrollableSize.width, 0.0)).x;
      break;
  }

  double scrollOffsetDelta;
  if (targetMin < scrollableMin) {
    if (targetMax > scrollableMax) {
      // The target is to big to fit inside the scrollable. The best we can do
      // is to center the target.
      double targetCenter = (targetMin + targetMax) / 2.0;
      double scrollableCenter = (scrollableMin + scrollableMax) / 2.0;
      scrollOffsetDelta = targetCenter - scrollableCenter;
    } else {
      scrollOffsetDelta = targetMin - scrollableMin;
    }
  } else if (targetMax > scrollableMax) {
    scrollOffsetDelta = targetMax - scrollableMax;
  } else {
    return new Future<Null>.value();
  }

  ExtentScrollBehavior scrollBehavior = scrollable.scrollBehavior;
  double scrollOffset = (scrollable.scrollOffset + scrollOffsetDelta)
    .clamp(scrollBehavior.minScrollOffset, scrollBehavior.maxScrollOffset);

  if (scrollOffset != scrollable.scrollOffset)
    return scrollable.scrollTo(scrollOffset, duration: duration, curve: curve);

  return new Future<Null>.value();
}