Commit 5c4c1b8d authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Cleaning up minor issues (#5779)

I did a pass through some of the code cleaning minor things up.
parent 411db2d5
...@@ -28,6 +28,8 @@ class DragDownDetails { ...@@ -28,6 +28,8 @@ class DragDownDetails {
} }
/// Signature for when a pointer has contacted the screen and might begin to move. /// Signature for when a pointer has contacted the screen and might begin to move.
///
/// See [DragGestureRecognizer.onDown].
typedef void GestureDragDownCallback(DragDownDetails details); typedef void GestureDragDownCallback(DragDownDetails details);
/// Details for [GestureDragStartCallback]. /// Details for [GestureDragStartCallback].
...@@ -44,6 +46,8 @@ class DragStartDetails { ...@@ -44,6 +46,8 @@ class DragStartDetails {
} }
/// Signature for when a pointer has contacted the screen and has begun to move. /// Signature for when a pointer has contacted the screen and has begun to move.
///
/// See [DragGestureRecognizer.onStart].
typedef void GestureDragStartCallback(DragStartDetails details); typedef void GestureDragStartCallback(DragStartDetails details);
/// Details for [GestureDragUpdateCallback]. /// Details for [GestureDragUpdateCallback].
...@@ -87,6 +91,8 @@ class DragUpdateDetails { ...@@ -87,6 +91,8 @@ class DragUpdateDetails {
/// Signature for when a pointer that is in contact with the screen and moving /// Signature for when a pointer that is in contact with the screen and moving
/// has moved again. /// has moved again.
///
/// See [DragGestureRecognizer.onUpdate].
typedef void GestureDragUpdateCallback(DragUpdateDetails details); typedef void GestureDragUpdateCallback(DragUpdateDetails details);
/// Details for [GestureDragEndCallback]. /// Details for [GestureDragEndCallback].
...@@ -107,10 +113,14 @@ class DragEndDetails { ...@@ -107,10 +113,14 @@ class DragEndDetails {
/// ///
/// The velocity at which the pointer was moving when it stopped contacting /// The velocity at which the pointer was moving when it stopped contacting
/// the screen is available in the `details`. /// the screen is available in the `details`.
///
/// See [DragGestureRecognizer.onEnd].
typedef void GestureDragEndCallback(DragEndDetails details); typedef void GestureDragEndCallback(DragEndDetails details);
/// Signature for when the pointer that previously triggered a /// Signature for when the pointer that previously triggered a
/// [GestureDragDownCallback] did not complete. /// [GestureDragDownCallback] did not complete.
///
/// See [DragGestureRecognizer.onCancel].
typedef void GestureDragCancelCallback(); typedef void GestureDragCancelCallback();
bool _isFlingGesture(Velocity velocity) { bool _isFlingGesture(Velocity velocity) {
......
...@@ -950,6 +950,18 @@ class PipelineOwner { ...@@ -950,6 +950,18 @@ class PipelineOwner {
} }
} }
/// The object that is managing semantics for this pipeline owner, if any.
///
/// An owner is created by [addSemanticsListener] the first time a listener is
/// added.
///
/// The owner is valid for as long as there are listeners. Once the last
/// listener is removed (by calling [SemanticsOwner.removeListener] on the
/// [semanticsOwner]), the [semanticsOwner] field will revert to null, and the
/// previous owner will be disposed.
///
/// When [semanticsOwner] is null, the [PipelineOwner] skips all steps
/// relating to semantics.
SemanticsOwner get semanticsOwner => _semanticsOwner; SemanticsOwner get semanticsOwner => _semanticsOwner;
SemanticsOwner _semanticsOwner; SemanticsOwner _semanticsOwner;
bool _debugDoingSemantics = false; bool _debugDoingSemantics = false;
......
...@@ -33,7 +33,7 @@ enum CrossFadeState { ...@@ -33,7 +33,7 @@ enum CrossFadeState {
/// animation crops overflowing children during the animation by aligning their /// animation crops overflowing children during the animation by aligning their
/// top edge, which means that the bottom will be clipped. /// top edge, which means that the bottom will be clipped.
class AnimatedCrossFade extends StatefulWidget { class AnimatedCrossFade extends StatefulWidget {
/// Creates a cross fade animation widget. /// Creates a cross-fade animation widget.
/// ///
/// The [duration] of the animation is the same for all components (fade in, /// The [duration] of the animation is the same for all components (fade in,
/// fade out, and size), and you can pass [Interval]s instead of [Curve]s in /// fade out, and size), and you can pass [Interval]s instead of [Curve]s in
...@@ -54,17 +54,14 @@ class AnimatedCrossFade extends StatefulWidget { ...@@ -54,17 +54,14 @@ class AnimatedCrossFade extends StatefulWidget {
} }
/// The child that is visible when [crossFadeState] is [showFirst]. It fades /// The child that is visible when [crossFadeState] is [showFirst]. It fades
/// out when transitioning from [showFirst] to [showSecond] and fades in /// out when transitioning from [showFirst] to [showSecond] and vice versa.
/// otherwise.
final Widget firstChild; final Widget firstChild;
/// The child that is visible when [crossFadeState] is [showSecond]. It fades /// The child that is visible when [crossFadeState] is [showSecond]. It fades
/// in when transitioning from [showFirst] to [showSecond] and fades out /// in when transitioning from [showFirst] to [showSecond] and vice versa.
/// otherwise.
final Widget secondChild; final Widget secondChild;
/// This field identifies the child that will be shown when the animation has /// The child that will be shown when the animation has completed.
/// completed.
final CrossFadeState crossFadeState; final CrossFadeState crossFadeState;
/// The duration of the whole orchestrated animation. /// The duration of the whole orchestrated animation.
...@@ -90,6 +87,16 @@ class _AnimatedCrossFadeState extends State<AnimatedCrossFade> { ...@@ -90,6 +87,16 @@ class _AnimatedCrossFadeState extends State<AnimatedCrossFade> {
Animation<double> _firstAnimation; Animation<double> _firstAnimation;
Animation<double> _secondAnimation; Animation<double> _secondAnimation;
@override
void initState() {
super.initState();
_controller = new AnimationController(duration: config.duration);
if (config.crossFadeState == CrossFadeState.showSecond)
_controller.value = 1.0;
_firstAnimation = _initAnimation(config.firstCurve, true);
_secondAnimation = _initAnimation(config.secondCurve, false);
}
Animation<double> _initAnimation(Curve curve, bool inverted) { Animation<double> _initAnimation(Curve curve, bool inverted) {
final CurvedAnimation animation = new CurvedAnimation( final CurvedAnimation animation = new CurvedAnimation(
parent: _controller, parent: _controller,
...@@ -102,16 +109,6 @@ class _AnimatedCrossFadeState extends State<AnimatedCrossFade> { ...@@ -102,16 +109,6 @@ class _AnimatedCrossFadeState extends State<AnimatedCrossFade> {
).animate(animation) : animation; ).animate(animation) : animation;
} }
@override
void initState() {
super.initState();
_controller = new AnimationController(duration: config.duration);
if (config.crossFadeState == CrossFadeState.showSecond)
_controller.value = 1.0;
_firstAnimation = _initAnimation(config.firstCurve, true);
_secondAnimation = _initAnimation(config.secondCurve, false);
}
@override @override
void dispose() { void dispose() {
_controller.dispose(); _controller.dispose();
...@@ -121,7 +118,12 @@ class _AnimatedCrossFadeState extends State<AnimatedCrossFade> { ...@@ -121,7 +118,12 @@ class _AnimatedCrossFadeState extends State<AnimatedCrossFade> {
@override @override
void didUpdateConfig(AnimatedCrossFade oldConfig) { void didUpdateConfig(AnimatedCrossFade oldConfig) {
super.didUpdateConfig(oldConfig); super.didUpdateConfig(oldConfig);
if (config.duration != oldConfig.duration)
_controller.duration = config.duration;
if (config.firstCurve != oldConfig.firstCurve)
_firstAnimation = _initAnimation(config.firstCurve, true);
if (config.secondCurve != oldConfig.secondCurve)
_secondAnimation = _initAnimation(config.secondCurve, false);
if (config.crossFadeState != oldConfig.crossFadeState) { if (config.crossFadeState != oldConfig.crossFadeState) {
switch (config.crossFadeState) { switch (config.crossFadeState) {
case CrossFadeState.showFirst: case CrossFadeState.showFirst:
...@@ -132,15 +134,6 @@ class _AnimatedCrossFadeState extends State<AnimatedCrossFade> { ...@@ -132,15 +134,6 @@ class _AnimatedCrossFadeState extends State<AnimatedCrossFade> {
break; break;
} }
} }
if (config.duration != oldConfig.duration)
_controller.duration = config.duration;
if (config.firstCurve != oldConfig.firstCurve) {
_firstAnimation = _initAnimation(config.firstCurve, true);
}
if (config.secondCurve != oldConfig.secondCurve) {
_secondAnimation = _initAnimation(config.secondCurve, false);
}
} }
@override @override
......
...@@ -134,8 +134,8 @@ class _DismissableState extends State<Dismissable> { ...@@ -134,8 +134,8 @@ class _DismissableState extends State<Dismissable> {
@override @override
void dispose() { void dispose() {
_moveController?.stop(); _moveController.dispose();
_resizeController?.stop(); _resizeController?.dispose();
super.dispose(); super.dispose();
} }
......
...@@ -2508,7 +2508,7 @@ class StatefulElement extends ComponentElement { ...@@ -2508,7 +2508,7 @@ class StatefulElement extends ComponentElement {
"inheritFromWidgetOfExactType($targetType) was called before ${_state.runtimeType}.initState() completed.\n" "inheritFromWidgetOfExactType($targetType) was called before ${_state.runtimeType}.initState() completed.\n"
"When an inherited widget changes, for example if the value of Theme.of() changes, " "When an inherited widget changes, for example if the value of Theme.of() changes, "
"its dependent widgets are rebuilt. If the dependent widget's reference to " "its dependent widgets are rebuilt. If the dependent widget's reference to "
"the inherited widget is in an constructor or an initState() method, " "the inherited widget is in a constructor or an initState() method, "
"then the rebuilt dependent widget will not reflect the changes in the " "then the rebuilt dependent widget will not reflect the changes in the "
"inherited widget.\n" "inherited widget.\n"
"Typically references to to inherited widgets should occur in widget build() methods.\n" "Typically references to to inherited widgets should occur in widget build() methods.\n"
......
...@@ -156,7 +156,6 @@ class Image extends StatefulWidget { ...@@ -156,7 +156,6 @@ class Image extends StatefulWidget {
/// Whether to continue showing the old image (true), or briefly show nothing /// Whether to continue showing the old image (true), or briefly show nothing
/// (false), when the image provider changes. /// (false), when the image provider changes.
// TODO(ianh): Find a better name.
final bool gaplessPlayback; final bool gaplessPlayback;
@override @override
......
...@@ -156,7 +156,7 @@ abstract class AnimatedWidgetBaseState<T extends ImplicitlyAnimatedWidget> exten ...@@ -156,7 +156,7 @@ abstract class AnimatedWidgetBaseState<T extends ImplicitlyAnimatedWidget> exten
@override @override
void dispose() { void dispose() {
_controller.stop(); _controller.dispose();
super.dispose(); super.dispose();
} }
......
...@@ -52,83 +52,6 @@ class LayoutBuilder extends RenderObjectWidget { ...@@ -52,83 +52,6 @@ class LayoutBuilder extends RenderObjectWidget {
// updateRenderObject is redundant with the logic in the LayoutBuilderElement below. // updateRenderObject is redundant with the logic in the LayoutBuilderElement below.
} }
class _RenderLayoutBuilder extends RenderBox with RenderObjectWithChildMixin<RenderBox> {
_RenderLayoutBuilder({
LayoutCallback callback,
}) : _callback = callback;
LayoutCallback get callback => _callback;
LayoutCallback _callback;
set callback(LayoutCallback value) {
if (value == _callback)
return;
_callback = value;
markNeedsLayout();
}
bool _debugThrowIfNotCheckingIntrinsics() {
assert(() {
if (!RenderObject.debugCheckingIntrinsics) {
throw new FlutterError(
'LayoutBuilder does not support returning intrinsic dimensions.\n'
'Calculating the intrinsic dimensions would require running the layout callback speculatively, '
'which might mutate the live render object tree.'
);
}
return true;
});
return true;
}
@override
double computeMinIntrinsicWidth(double height) {
assert(_debugThrowIfNotCheckingIntrinsics());
return 0.0;
}
@override
double computeMaxIntrinsicWidth(double height) {
assert(_debugThrowIfNotCheckingIntrinsics());
return 0.0;
}
@override
double computeMinIntrinsicHeight(double width) {
assert(_debugThrowIfNotCheckingIntrinsics());
return 0.0;
}
@override
double computeMaxIntrinsicHeight(double width) {
assert(_debugThrowIfNotCheckingIntrinsics());
return 0.0;
}
@override
void performLayout() {
assert(callback != null);
invokeLayoutCallback(callback);
if (child != null) {
child.layout(constraints, parentUsesSize: true);
size = constraints.constrain(child.size);
} else {
size = constraints.biggest;
}
}
@override
bool hitTestChildren(HitTestResult result, { Point position }) {
return child?.hitTest(result, position: position) ?? false;
}
@override
void paint(PaintingContext context, Offset offset) {
if (child != null)
context.paintChild(child, offset);
}
}
// TODO(ianh): move this class up to just below its widget.
class _LayoutBuilderElement extends RenderObjectElement { class _LayoutBuilderElement extends RenderObjectElement {
_LayoutBuilderElement(LayoutBuilder widget) : super(widget); _LayoutBuilderElement(LayoutBuilder widget) : super(widget);
...@@ -220,6 +143,82 @@ class _LayoutBuilderElement extends RenderObjectElement { ...@@ -220,6 +143,82 @@ class _LayoutBuilderElement extends RenderObjectElement {
} }
} }
class _RenderLayoutBuilder extends RenderBox with RenderObjectWithChildMixin<RenderBox> {
_RenderLayoutBuilder({
LayoutCallback callback,
}) : _callback = callback;
LayoutCallback get callback => _callback;
LayoutCallback _callback;
set callback(LayoutCallback value) {
if (value == _callback)
return;
_callback = value;
markNeedsLayout();
}
bool _debugThrowIfNotCheckingIntrinsics() {
assert(() {
if (!RenderObject.debugCheckingIntrinsics) {
throw new FlutterError(
'LayoutBuilder does not support returning intrinsic dimensions.\n'
'Calculating the intrinsic dimensions would require running the layout callback speculatively, '
'which might mutate the live render object tree.'
);
}
return true;
});
return true;
}
@override
double computeMinIntrinsicWidth(double height) {
assert(_debugThrowIfNotCheckingIntrinsics());
return 0.0;
}
@override
double computeMaxIntrinsicWidth(double height) {
assert(_debugThrowIfNotCheckingIntrinsics());
return 0.0;
}
@override
double computeMinIntrinsicHeight(double width) {
assert(_debugThrowIfNotCheckingIntrinsics());
return 0.0;
}
@override
double computeMaxIntrinsicHeight(double width) {
assert(_debugThrowIfNotCheckingIntrinsics());
return 0.0;
}
@override
void performLayout() {
assert(callback != null);
invokeLayoutCallback(callback);
if (child != null) {
child.layout(constraints, parentUsesSize: true);
size = constraints.constrain(child.size);
} else {
size = constraints.biggest;
}
}
@override
bool hitTestChildren(HitTestResult result, { Point position }) {
return child?.hitTest(result, position: position) ?? false;
}
@override
void paint(PaintingContext context, Offset offset) {
if (child != null)
context.paintChild(child, offset);
}
}
void _debugReportException(String context, dynamic exception, StackTrace stack) { void _debugReportException(String context, dynamic exception, StackTrace stack) {
FlutterError.reportError(new FlutterErrorDetails( FlutterError.reportError(new FlutterErrorDetails(
exception: exception, exception: exception,
......
...@@ -83,7 +83,7 @@ class MimicOverlayEntry { ...@@ -83,7 +83,7 @@ class MimicOverlayEntry {
void dispose() { void dispose() {
_targetKey = null; _targetKey = null;
_curve = null; _curve = null;
_controller?.stop(); _controller?.dispose();
_controller = null; _controller = null;
_handle.stopMimic(); _handle.stopMimic();
_handle = null; _handle = null;
......
...@@ -80,9 +80,10 @@ abstract class Route<T> { ...@@ -80,9 +80,10 @@ abstract class Route<T> {
/// is replaced, or if the navigator itself is disposed). /// is replaced, or if the navigator itself is disposed).
void dispose() { } void dispose() { }
// If the route's transition can be popped via a user gesture (e.g. the iOS /// If the route's transition can be popped via a user gesture (e.g. the iOS
// back gesture), this should return a controller object that can be used /// back gesture), this should return a controller object that can be used to
// to control the transition animation's progress. /// control the transition animation's progress. Otherwise, it should return
/// null.
NavigationGestureController startPopGesture(NavigatorState navigator) { NavigationGestureController startPopGesture(NavigatorState navigator) {
return null; return null;
} }
...@@ -158,15 +159,28 @@ class NavigatorObserver { ...@@ -158,15 +159,28 @@ class NavigatorObserver {
void didStopUserGesture() { } void didStopUserGesture() { }
} }
// An interface to be implemented by the Route, allowing its transition /// Interface describing an object returned by the [Route.startPopGesture]
// animation to be controlled by a drag. /// method, allowing the route's transition animations to be controlled by a
/// drag or other user gesture.
abstract class NavigationGestureController { abstract class NavigationGestureController {
/// Configures the NavigationGestureController and tells the given [Navigator] that
/// a gesture has started.
NavigationGestureController(this._navigator) { NavigationGestureController(this._navigator) {
// Disable Hero transitions until the gesture is complete. // Disable Hero transitions until the gesture is complete.
_navigator.didStartUserGesture(); _navigator.didStartUserGesture();
} }
// Must be called when the gesture is done. /// The navigator that this object is controlling.
@protected
NavigatorState get navigator => _navigator;
NavigatorState _navigator;
/// Release the resources used by this object. The object is no longer usable
/// after this method is called.
///
/// Must be called when the gesture is done.
///
/// Calling this method notifies the navigator that the gesture has completed.
void dispose() { void dispose() {
_navigator.didStopUserGesture(); _navigator.didStopUserGesture();
_navigator = null; _navigator = null;
...@@ -179,10 +193,6 @@ abstract class NavigationGestureController { ...@@ -179,10 +193,6 @@ abstract class NavigationGestureController {
// The drag gesture has ended with a horizontal motion of // The drag gesture has ended with a horizontal motion of
// [fractionalVelocity] as a fraction of screen width per second. // [fractionalVelocity] as a fraction of screen width per second.
void dragEnd(double fractionalVelocity); void dragEnd(double fractionalVelocity);
@protected
NavigatorState get navigator => _navigator;
NavigatorState _navigator;
} }
/// Signature for the [Navigator.popUntil] predicate argument. /// Signature for the [Navigator.popUntil] predicate argument.
...@@ -363,6 +373,8 @@ class NavigatorState extends State<Navigator> { ...@@ -363,6 +373,8 @@ class NavigatorState extends State<Navigator> {
bool _debugLocked = false; // used to prevent re-entrant calls to push, pop, and friends bool _debugLocked = false; // used to prevent re-entrant calls to push, pop, and friends
/// Looks up the route with the given name using [Navigator.onGenerateRoute],
/// and then [push]es that route.
void pushNamed(String name) { void pushNamed(String name) {
assert(!_debugLocked); assert(!_debugLocked);
assert(name != null); assert(name != null);
...@@ -376,6 +388,15 @@ class NavigatorState extends State<Navigator> { ...@@ -376,6 +388,15 @@ class NavigatorState extends State<Navigator> {
push(route); push(route);
} }
/// Adds the given route to the navigator's history, and transitions to it.
///
/// The new route and the previous route (if any) are notified (see
/// [Route.didPush] and [Route.didChangeNext]). If the [Navigator] has an
/// [Navigator.observer], it will be notified as well (see
/// [NavigatorObserver.didPush]).
///
/// Ongoing gestures within the current route are canceled when a new route is
/// pushed.
void push(Route<dynamic> route) { void push(Route<dynamic> route) {
assert(!_debugLocked); assert(!_debugLocked);
assert(() { _debugLocked = true; return true; }); assert(() { _debugLocked = true; return true; });
...@@ -396,6 +417,14 @@ class NavigatorState extends State<Navigator> { ...@@ -396,6 +417,14 @@ class NavigatorState extends State<Navigator> {
_cancelActivePointers(); _cancelActivePointers();
} }
/// Replaces a route that is not currently visible with a new route.
///
/// The new route and the route below the new route (if any) are notified
/// (see [Route.didReplace] and [Route.didChangeNext]). The navigator observer
/// is not notified. The old route is disposed (see [Route.dispose]).
///
/// This can be useful in combination with [removeRouteBelow] when building a
/// non-linear user experience.
void replace({ Route<dynamic> oldRoute, Route<dynamic> newRoute }) { void replace({ Route<dynamic> oldRoute, Route<dynamic> newRoute }) {
assert(!_debugLocked); assert(!_debugLocked);
assert(oldRoute != null); assert(oldRoute != null);
...@@ -425,17 +454,29 @@ class NavigatorState extends State<Navigator> { ...@@ -425,17 +454,29 @@ class NavigatorState extends State<Navigator> {
oldRoute._navigator = null; oldRoute._navigator = null;
}); });
assert(() { _debugLocked = false; return true; }); assert(() { _debugLocked = false; return true; });
_cancelActivePointers();
} }
void replaceRouteBefore({ Route<dynamic> anchorRoute, Route<dynamic> newRoute }) { /// Replaces a route that is not currently visible with a new route.
///
/// The route to be removed is the one below the given `anchorRoute`. That
/// route must not be the first route in the history.
///
/// In every other way, this acts the same as [replace].
void replaceRouteBelow({ Route<dynamic> anchorRoute, Route<dynamic> newRoute }) {
assert(anchorRoute != null); assert(anchorRoute != null);
assert(anchorRoute._navigator == this); assert(anchorRoute._navigator == this);
assert(_history.indexOf(anchorRoute) > 0); assert(_history.indexOf(anchorRoute) > 0);
replace(oldRoute: _history[_history.indexOf(anchorRoute)-1], newRoute: newRoute); replace(oldRoute: _history[_history.indexOf(anchorRoute)-1], newRoute: newRoute);
} }
void removeRouteBefore(Route<dynamic> anchorRoute) { /// Removes the route below the given `anchorRoute`. The route to be removed
/// must not currently be visible. The `anchorRoute` must not be the first
/// route in the history.
///
/// The removed route is disposed (see [Route.dispose]). The route prior to
/// the removed route, if any, is notified (see [Route.didChangeNext]). The
/// navigator observer is not notified.
void removeRouteBelow(Route<dynamic> anchorRoute) {
assert(!_debugLocked); assert(!_debugLocked);
assert(() { _debugLocked = true; return true; }); assert(() { _debugLocked = true; return true; });
assert(anchorRoute._navigator == this); assert(anchorRoute._navigator == this);
...@@ -453,9 +494,21 @@ class NavigatorState extends State<Navigator> { ...@@ -453,9 +494,21 @@ class NavigatorState extends State<Navigator> {
targetRoute._navigator = null; targetRoute._navigator = null;
}); });
assert(() { _debugLocked = false; return true; }); assert(() { _debugLocked = false; return true; });
_cancelActivePointers();
} }
/// Removes the top route in the [Navigator]'s history.
///
/// If an argument is provided, that argument will be the return value of the
/// route (see [Route.didPop]).
///
/// If there are any routes left on the history, the top remaining route is
/// notified (see [Route.didPopNext]), and the method returns true. In that
/// case, if the [Navigator] has an [Navigator.observer], it will be notified
/// as well (see [NavigatorObserver.didPop]). Otherwise, if the popped route
/// was the last route, the method returns false.
///
/// Ongoing gestures within the current route are canceled when a route is
/// popped.
bool pop([dynamic result]) { bool pop([dynamic result]) {
assert(!_debugLocked); assert(!_debugLocked);
assert(() { _debugLocked = true; return true; }); assert(() { _debugLocked = true; return true; });
...@@ -487,6 +540,7 @@ class NavigatorState extends State<Navigator> { ...@@ -487,6 +540,7 @@ class NavigatorState extends State<Navigator> {
return true; return true;
} }
/// Repeatedly calls [pop] until the given `predicate` returns true.
void popUntil(RoutePredicate predicate) { void popUntil(RoutePredicate predicate) {
while (!predicate(_history.last)) while (!predicate(_history.last))
pop(); pop();
...@@ -533,8 +587,7 @@ class NavigatorState extends State<Navigator> { ...@@ -533,8 +587,7 @@ class NavigatorState extends State<Navigator> {
} }
void _cancelActivePointers() { void _cancelActivePointers() {
// This mechanism is far from perfect. See the issue below for more details: // TODO(abarth): This mechanism is far from perfect. See https://github.com/flutter/flutter/issues/4770
// https://github.com/flutter/flutter/issues/4770
RenderAbsorbPointer absorber = _overlayKey.currentContext?.ancestorRenderObjectOfType(const TypeMatcher<RenderAbsorbPointer>()); RenderAbsorbPointer absorber = _overlayKey.currentContext?.ancestorRenderObjectOfType(const TypeMatcher<RenderAbsorbPointer>());
setState(() { setState(() {
absorber?.absorbing = true; absorber?.absorbing = true;
......
...@@ -109,6 +109,9 @@ abstract class TransitionRoute<T> extends OverlayRoute<T> { ...@@ -109,6 +109,9 @@ abstract class TransitionRoute<T> extends OverlayRoute<T> {
Animation<double> get animation => _animation; Animation<double> get animation => _animation;
Animation<double> _animation; Animation<double> _animation;
/// The animation controller that the route uses to drive the transitions.
///
/// The animation itself is exposed by the [animation] property.
@protected @protected
AnimationController get controller => _controller; AnimationController get controller => _controller;
AnimationController _controller; AnimationController _controller;
......
...@@ -780,9 +780,21 @@ class ScrollNotification extends Notification { ...@@ -780,9 +780,21 @@ class ScrollNotification extends Notification {
/// The scrollable that scrolled. /// The scrollable that scrolled.
final ScrollableState scrollable; final ScrollableState scrollable;
/// The details from the underlying [DragGestureRecognizer] gesture, if the
/// notification ultimately came from a [DragGestureRecognizer.onStart]
/// handler; otherwise null.
DragStartDetails get dragStartDetails => kind == ScrollNotificationKind.started ? _details : null; DragStartDetails get dragStartDetails => kind == ScrollNotificationKind.started ? _details : null;
/// The details from the underlying [DragGestureRecognizer] gesture, if the
/// notification ultimately came from a [DragGestureRecognizer.onUpdate]
/// handler; otherwise null.
DragUpdateDetails get dragUpdateDetails => kind == ScrollNotificationKind.updated ? _details : null; DragUpdateDetails get dragUpdateDetails => kind == ScrollNotificationKind.updated ? _details : null;
/// The details from the underlying [DragGestureRecognizer] gesture, if the
/// notification ultimately came from a [DragGestureRecognizer.onEnd]
/// handler; otherwise null.
DragEndDetails get dragEndDetails => kind == ScrollNotificationKind.ended ? _details : null; DragEndDetails get dragEndDetails => kind == ScrollNotificationKind.ended ? _details : null;
final dynamic _details; final dynamic _details;
/// The number of scrollable widgets that have already received this /// The number of scrollable widgets that have already received this
......
...@@ -334,6 +334,11 @@ class PositionedTransition extends AnimatedWidget { ...@@ -334,6 +334,11 @@ class PositionedTransition extends AnimatedWidget {
/// ///
/// * [PositionedTransition] /// * [PositionedTransition]
class RelativePositionedTransition extends AnimatedWidget { class RelativePositionedTransition extends AnimatedWidget {
/// Create an animated version of [Positioned].
///
/// Each frame, the [Positioned] widget will be configured to represent the
/// current value of the [rect] argument assuming that the stack has the given
/// [size]. Both [rect] and [size] must be non-null.
RelativePositionedTransition({ RelativePositionedTransition({
Key key, Key key,
@required Animation<Rect> rect, @required Animation<Rect> rect,
...@@ -342,6 +347,8 @@ class RelativePositionedTransition extends AnimatedWidget { ...@@ -342,6 +347,8 @@ class RelativePositionedTransition extends AnimatedWidget {
}) : super(key: key, animation: rect); }) : super(key: key, animation: rect);
/// The animation that controls the child's size and position. /// The animation that controls the child's size and position.
///
/// See also [size].
Animation<Rect> get rect => animation; Animation<Rect> get rect => animation;
/// The [Positioned] widget's offsets are relative to a box of this /// The [Positioned] widget's offsets are relative to a box of this
......
...@@ -210,7 +210,7 @@ void main() { ...@@ -210,7 +210,7 @@ void main() {
await runNavigatorTest( await runNavigatorTest(
tester, tester,
host, host,
() { host.removeRouteBefore(second); }, () { host.removeRouteBelow(second); },
<String>[ <String>[
'first: dispose', 'first: dispose',
] ]
...@@ -251,7 +251,7 @@ void main() { ...@@ -251,7 +251,7 @@ void main() {
await runNavigatorTest( await runNavigatorTest(
tester, tester,
host, host,
() { host.removeRouteBefore(four); }, () { host.removeRouteBelow(four); },
<String>[ <String>[
'second: didChangeNext four', 'second: didChangeNext four',
'three: dispose', 'three: dispose',
...@@ -317,7 +317,7 @@ void main() { ...@@ -317,7 +317,7 @@ void main() {
await runNavigatorTest( await runNavigatorTest(
tester, tester,
host, host,
() { host.replaceRouteBefore(anchorRoute: routeC, newRoute: routeB = new TestRoute('b')); }, () { host.replaceRouteBelow(anchorRoute: routeC, newRoute: routeB = new TestRoute('b')); },
<String>[ <String>[
'b: install', 'b: install',
'b: didReplace B', 'b: didReplace B',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment