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();
}