Merge pull request #1354 from abarth/fn3_ensure_widgets_is_visible
Add ensureWidgetIsVisible to fn3
This commit is contained in:
commit
6c3b20be8e
@ -396,6 +396,8 @@ typedef void ElementVisitor(Element element);
|
|||||||
abstract class BuildContext {
|
abstract class BuildContext {
|
||||||
InheritedWidget inheritedWidgetOfType(Type targetType);
|
InheritedWidget inheritedWidgetOfType(Type targetType);
|
||||||
RenderObject findRenderObject();
|
RenderObject findRenderObject();
|
||||||
|
|
||||||
|
void visitAncestorElements(bool visitor(Element element));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Elements are the instantiations of Widget configurations.
|
/// Elements are the instantiations of Widget configurations.
|
||||||
@ -607,6 +609,12 @@ abstract class Element<T extends Widget> implements BuildContext {
|
|||||||
|
|
||||||
RenderObject findRenderObject() => renderObject;
|
RenderObject findRenderObject() => renderObject;
|
||||||
|
|
||||||
|
void visitAncestorElements(bool visitor(Element element)) {
|
||||||
|
Element ancestor = _parent;
|
||||||
|
while (ancestor != null && visitor(ancestor))
|
||||||
|
ancestor = ancestor._parent;
|
||||||
|
}
|
||||||
|
|
||||||
void dependenciesChanged() {
|
void dependenciesChanged() {
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
@ -207,8 +207,62 @@ abstract class ScrollableState<T extends Scrollable> extends State<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(abarth): findScrollableAncestor
|
ScrollableState findScrollableAncestor(BuildContext context) {
|
||||||
// TODO(abarth): ensureWidgetIsVisible
|
ScrollableState result;
|
||||||
|
context.visitAncestorElements((Element element) {
|
||||||
|
if (element is StatefulComponentElement) {
|
||||||
|
if (element.state is ScrollableState) {
|
||||||
|
result = element.state;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future ensureWidgetIsVisible(BuildContext context, { Duration duration, Curve curve }) {
|
||||||
|
assert(context.findRenderObject() is RenderBox);
|
||||||
|
// TODO(abarth): This function doesn't handle nested scrollable widgets.
|
||||||
|
|
||||||
|
ScrollableState scrollable = findScrollableAncestor(context);
|
||||||
|
if (scrollable == null)
|
||||||
|
return new Future.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 scrollOffsetDelta;
|
||||||
|
switch (scrollable.config.scrollDirection) {
|
||||||
|
case ScrollDirection.vertical:
|
||||||
|
Point targetCenter = targetBox.localToGlobal(new Point(0.0, targetSize.height / 2.0));
|
||||||
|
Point scrollableCenter = scrollableBox.localToGlobal(new Point(0.0, scrollableSize.height / 2.0));
|
||||||
|
scrollOffsetDelta = targetCenter.y - scrollableCenter.y;
|
||||||
|
break;
|
||||||
|
case ScrollDirection.horizontal:
|
||||||
|
Point targetCenter = targetBox.localToGlobal(new Point(targetSize.width / 2.0, 0.0));
|
||||||
|
Point scrollableCenter = scrollableBox.localToGlobal(new Point(scrollableSize.width / 2.0, 0.0));
|
||||||
|
scrollOffsetDelta = targetCenter.x - scrollableCenter.x;
|
||||||
|
break;
|
||||||
|
case ScrollDirection.both:
|
||||||
|
assert(false); // See https://github.com/flutter/engine/issues/888
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
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.value();
|
||||||
|
}
|
||||||
|
|
||||||
/// A simple scrollable widget that has a single child. Use this component if
|
/// A simple scrollable widget that has a single child. Use this component if
|
||||||
/// you are not worried about offscreen widgets consuming resources.
|
/// you are not worried about offscreen widgets consuming resources.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user