diff --git a/packages/flutter/lib/material.dart b/packages/flutter/lib/material.dart index 8f4df1b754b..a2807153f2e 100644 --- a/packages/flutter/lib/material.dart +++ b/packages/flutter/lib/material.dart @@ -33,9 +33,11 @@ export 'src/material/material.dart'; export 'src/material/material_app.dart'; export 'src/material/material_button.dart'; export 'src/material/material_list.dart'; -export 'src/material/popup_menu_item.dart'; +export 'src/material/page.dart'; export 'src/material/popup_menu.dart'; +export 'src/material/popup_menu_item.dart'; export 'src/material/progress_indicator.dart'; +export 'src/material/radial_reaction.dart'; export 'src/material/radio.dart'; export 'src/material/raised_button.dart'; export 'src/material/scaffold.dart'; @@ -44,11 +46,10 @@ export 'src/material/shadows.dart'; export 'src/material/snack_bar.dart'; export 'src/material/switch.dart'; export 'src/material/tabs.dart'; -export 'src/material/theme_data.dart'; export 'src/material/theme.dart'; +export 'src/material/theme_data.dart'; export 'src/material/title.dart'; export 'src/material/tool_bar.dart'; export 'src/material/typography.dart'; -export 'src/material/radial_reaction.dart'; export 'widgets.dart'; diff --git a/packages/flutter/lib/src/animation/performance.dart b/packages/flutter/lib/src/animation/performance.dart index 981e507baa3..879d1c0cf23 100644 --- a/packages/flutter/lib/src/animation/performance.dart +++ b/packages/flutter/lib/src/animation/performance.dart @@ -168,7 +168,7 @@ class Performance extends PerformanceView { /// Returns a [PerformanceView] for this performance, /// so that a pointer to this object can be passed around without - /// allowing users of that pointer to mutate the AnimationPerformance state. + /// allowing users of that pointer to mutate the Performance state. PerformanceView get view => this; /// The length of time this performance should last diff --git a/packages/flutter/lib/src/material/dialog.dart b/packages/flutter/lib/src/material/dialog.dart index a4d6e505644..4c041eb091d 100644 --- a/packages/flutter/lib/src/material/dialog.dart +++ b/packages/flutter/lib/src/material/dialog.dart @@ -124,7 +124,9 @@ class _DialogRoute extends ModalRoute { Duration get transitionDuration => const Duration(milliseconds: 150); Color get barrierColor => Colors.black54; - Widget buildModalWidget(BuildContext context) { + Widget buildPage(BuildContext context) => child; + + Widget buildTransition(BuildContext context, PerformanceView performance, Widget child) { return new FadeTransition( performance: performance, opacity: new AnimatedValue(0.0, end: 1.0, curve: Curves.easeOut), diff --git a/packages/flutter/lib/src/material/material_app.dart b/packages/flutter/lib/src/material/material_app.dart index 1d35a92bf8a..c34d4da5fb6 100644 --- a/packages/flutter/lib/src/material/material_app.dart +++ b/packages/flutter/lib/src/material/material_app.dart @@ -8,6 +8,7 @@ import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; +import 'page.dart'; import 'theme.dart'; import 'title.dart'; @@ -95,13 +96,12 @@ class _MaterialAppState extends State { final HeroController _heroController = new HeroController(); Route _generateRoute(NamedRouteSettings settings) { - return new HeroPageRoute( + return new MaterialPageRoute( builder: (BuildContext context) { RouteBuilder builder = config.routes[settings.name] ?? config.onGenerateRoute(settings.name); return builder(new RouteArguments(context: context)); }, - settings: settings, - heroController: _heroController + settings: settings ); } @@ -118,7 +118,8 @@ class _MaterialAppState extends State { title: config.title, child: new Navigator( key: _navigator, - onGenerateRoute: _generateRoute + onGenerateRoute: _generateRoute, + observer: _heroController ) ) ) diff --git a/packages/flutter/lib/src/material/page.dart b/packages/flutter/lib/src/material/page.dart new file mode 100644 index 00000000000..f4f0fe62e81 --- /dev/null +++ b/packages/flutter/lib/src/material/page.dart @@ -0,0 +1,73 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/animation.dart'; +import 'package:flutter/widgets.dart'; + +class _MaterialPageTransition extends TransitionWithChild { + _MaterialPageTransition({ + Key key, + PerformanceView performance, + Widget child + }) : super(key: key, + performance: performance, + child: child); + + final AnimatedValue _position = + new AnimatedValue(const Point(0.0, 75.0), end: Point.origin, curve: Curves.easeOut); + + final AnimatedValue _opacity = + new AnimatedValue(0.0, end: 1.0, curve: Curves.easeOut); + + Widget buildWithChild(BuildContext context, Widget child) { + performance.updateVariable(_position); + performance.updateVariable(_opacity); + Matrix4 transform = new Matrix4.identity() + ..translate(_position.value.x, _position.value.y); + return new Transform( + transform: transform, + // TODO(ianh): tell the transform to be un-transformed for hit testing + child: new Opacity( + opacity: _opacity.value, + child: child + ) + ); + } +} + +class MaterialPageRoute extends ModalRoute { + MaterialPageRoute({ + this.builder, + NamedRouteSettings settings: const NamedRouteSettings() + }) : super(settings: settings) { + assert(builder != null); + assert(opaque); + } + + final WidgetBuilder builder; + + Duration get transitionDuration => const Duration(milliseconds: 150); + + bool get opaque => true; + + Widget buildPage(BuildContext context) { + Widget result = builder(context); + assert(() { + if (result == null) + debugPrint('The builder for route \'${settings.name}\' returned null. Route builders must never return null.'); + assert(result != null && 'A route builder returned null. See the previous log message for details.' is String); + return true; + }); + return result; + } + + Widget buildTransition(BuildContext context, PerformanceView performance, Widget child) { + return new _MaterialPageTransition( + performance: performance, + child: child + ); + } + + String get debugLabel => '${super.debugLabel}(${settings.name})'; +} diff --git a/packages/flutter/lib/src/material/popup_menu.dart b/packages/flutter/lib/src/material/popup_menu.dart index 26af33e6962..c6afa49d4d7 100644 --- a/packages/flutter/lib/src/material/popup_menu.dart +++ b/packages/flutter/lib/src/material/popup_menu.dart @@ -110,7 +110,7 @@ class _MenuRoute extends ModalRoute { bool get opaque => false; Duration get transitionDuration => _kMenuDuration; - Widget buildModalWidget(BuildContext context) => new _PopupMenu(route: this); + Widget buildPage(BuildContext context) => new _PopupMenu(route: this); } Future showMenu({ BuildContext context, ModalPosition position, List items, int level: 4 }) { diff --git a/packages/flutter/lib/src/widgets/hero_controller.dart b/packages/flutter/lib/src/widgets/hero_controller.dart index fb44db96032..3d3bdc63a1d 100644 --- a/packages/flutter/lib/src/widgets/hero_controller.dart +++ b/packages/flutter/lib/src/widgets/hero_controller.dart @@ -10,71 +10,49 @@ import 'framework.dart'; import 'heroes.dart'; import 'navigator.dart'; import 'overlay.dart'; -import 'page.dart'; +import 'routes.dart'; -class HeroPageRoute extends PageRoute { - HeroPageRoute({ - WidgetBuilder builder, - NamedRouteSettings settings: const NamedRouteSettings(), - this.heroController - }) : super(builder: builder, settings: settings); - - final HeroController heroController; - NavigatorState _navigator; - - void didPush(OverlayState overlay, OverlayEntry insertionPoint) { - super.didPush(overlay, insertionPoint); - // TODO(abarth): Pass the NavigatorState explicitly. - if (overlay != null) { - _navigator = Navigator.of(overlay.context); - heroController?.didPush(_navigator, this); - } - } - - void didPop(dynamic result) { - super.didPop(result); - if (_navigator != null) { - heroController?.didPop(_navigator, this); - _navigator = null; - } - } -} - -class HeroController { +class HeroController extends NavigatorObserver { HeroController() { _party = new HeroParty(onQuestFinished: _handleQuestFinished); } HeroParty _party; PerformanceView _performance; - HeroPageRoute _from; - HeroPageRoute _to; + ModalRoute _from; + ModalRoute _to; final List _overlayEntries = new List(); - void didPush(NavigatorState navigator, HeroPageRoute route) { + void didPushModal(Route route) { + assert(navigator != null); assert(route != null); - assert(route.performance != null); - Route from = navigator.currentRoute; - if (from is HeroPageRoute) - _from = from; - _to = route; - _performance = route.performance; - _checkForHeroQuest(); - } - - void didPop(NavigatorState navigator, HeroPageRoute route) { - assert(route != null); - assert(route.performance != null); - Route to = navigator.currentRoute; - if (to is HeroPageRoute) { - _to = to; - _from = route; + if (route is ModalRoute) { // as opposed to StateRoute, say + assert(route.performance != null); + Route from = navigator.currentRoute; + if (from is ModalRoute) // as opposed to the many other types of routes, or null + _from = from; + _to = route; _performance = route.performance; _checkForHeroQuest(); } } + void didPopModal(Route route) { + assert(navigator != null); + assert(route != null); + if (route is ModalRoute) { // as opposed to StateRoute, say + assert(route.performance != null); + Route to = navigator.currentRoute; + if (to is ModalRoute) { // as opposed to the many other types of routes + _to = to; + _from = route; + _performance = route.performance; + _checkForHeroQuest(); + } + } + } + void _checkForHeroQuest() { if (_from != null && _to != null && _from != _to) { _to.offstage = _to.performance.status != PerformanceStatus.completed; @@ -123,10 +101,9 @@ class HeroController { Set mostValuableKeys = _getMostValuableKeys(); Map heroesFrom = _party.isEmpty ? - Hero.of(_from.pageKey.currentContext, mostValuableKeys) : _party.getHeroesToAnimate(); + Hero.of(_from.subtreeContext, mostValuableKeys) : _party.getHeroesToAnimate(); - BuildContext context = _to.pageKey.currentContext; - Map heroesTo = Hero.of(context, mostValuableKeys); + Map heroesTo = Hero.of(_to.subtreeContext, mostValuableKeys); _to.offstage = false; PerformanceView performance = _performance; @@ -136,7 +113,6 @@ class HeroController { curve = new Interval(performance.progress, 1.0, curve: curve); } - NavigatorState navigator = Navigator.of(context); _party.animate(heroesFrom, heroesTo, _getAnimationArea(navigator.context), curve); _removeHeroesFromOverlay(); Iterable heroes = _party.getWidgets(navigator.context, performance); diff --git a/packages/flutter/lib/src/widgets/modal_barrier.dart b/packages/flutter/lib/src/widgets/modal_barrier.dart index 739a710a01a..1f5fe302999 100644 --- a/packages/flutter/lib/src/widgets/modal_barrier.dart +++ b/packages/flutter/lib/src/widgets/modal_barrier.dart @@ -2,32 +2,30 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:async'; - import 'package:flutter/animation.dart'; import 'basic.dart'; -import 'focus.dart'; import 'framework.dart'; import 'navigator.dart'; -import 'routes.dart'; -import 'status_transitions.dart'; import 'transitions.dart'; -const Color _kTransparent = const Color(0x00000000); +const Color kTransparent = const Color(0x00000000); class ModalBarrier extends StatelessComponent { ModalBarrier({ Key key, - this.color: _kTransparent + this.color: kTransparent, + this.dismissable: true }) : super(key: key); final Color color; + final bool dismissable; Widget build(BuildContext context) { return new Listener( onPointerDown: (_) { - Navigator.of(context).pop(); + if (dismissable) + Navigator.of(context).pop(); }, child: new ConstrainedBox( constraints: const BoxConstraints.expand(), @@ -45,11 +43,13 @@ class AnimatedModalBarrier extends StatelessComponent { AnimatedModalBarrier({ Key key, this.color, - this.performance + this.performance, + this.dismissable: true }) : super(key: key); final AnimatedColorValue color; final PerformanceView performance; + final bool dismissable; Widget build(BuildContext context) { return new BuilderTransition( @@ -58,69 +58,12 @@ class AnimatedModalBarrier extends StatelessComponent { builder: (BuildContext context) { return new IgnorePointer( ignoring: performance.status == PerformanceStatus.reverse, - child: new ModalBarrier(color: color.value) + child: new ModalBarrier( + color: color.value, + dismissable: dismissable + ) ); } ); } } - -class _ModalScope extends StatusTransitionComponent { - _ModalScope({ - Key key, - ModalRoute route, - this.child - }) : route = route, super(key: key, performance: route.performance); - - final ModalRoute route; - final Widget child; - - Widget build(BuildContext context) { - Widget focus = new Focus( - key: new GlobalObjectKey(route), - child: new IgnorePointer( - ignoring: route.performance.status == PerformanceStatus.reverse, - child: child - ) - ); - ModalPosition position = route.position; - if (position == null) - return focus; - return new Positioned( - top: position.top, - right: position.right, - bottom: position.bottom, - left: position.left, - child: focus - ); - } -} - -class ModalPosition { - const ModalPosition({ this.top, this.right, this.bottom, this.left }); - final double top; - final double right; - final double bottom; - final double left; -} - -abstract class ModalRoute extends TransitionRoute { - ModalRoute({ Completer completer }) : super(completer: completer); - - ModalPosition get position => null; - Color get barrierColor => _kTransparent; - Widget buildModalWidget(BuildContext context); - - Widget _buildModalBarrier(BuildContext context) { - return new AnimatedModalBarrier( - color: new AnimatedColorValue(_kTransparent, end: barrierColor, curve: Curves.ease), - performance: performance - ); - } - - Widget _buildModalScope(BuildContext context) { - return new _ModalScope(route: this, child: buildModalWidget(context)); - } - - List get builders => [ _buildModalBarrier, _buildModalScope ]; -} diff --git a/packages/flutter/lib/src/widgets/navigator.dart b/packages/flutter/lib/src/widgets/navigator.dart index 8223aacf412..56a98c55274 100644 --- a/packages/flutter/lib/src/widgets/navigator.dart +++ b/packages/flutter/lib/src/widgets/navigator.dart @@ -21,17 +21,26 @@ class NamedRouteSettings { typedef Route RouteFactory(NamedRouteSettings settings); +class NavigatorObserver { + NavigatorState _navigator; + NavigatorState get navigator => _navigator; + void didPopModal(Route route) { } + void didPushModal(Route route) { } +} + class Navigator extends StatefulComponent { Navigator({ Key key, this.onGenerateRoute, - this.onUnknownRoute + this.onUnknownRoute, + this.observer }) : super(key: key) { assert(onGenerateRoute != null); } final RouteFactory onGenerateRoute; final RouteFactory onUnknownRoute; + final NavigatorObserver observer; static const String defaultRouteName = '/'; @@ -57,9 +66,24 @@ class NavigatorState extends State { void initState() { super.initState(); + assert(config.observer == null || config.observer.navigator == null); + config.observer?._navigator = this; push(config.onGenerateRoute(new NamedRouteSettings(name: Navigator.defaultRouteName))); } + void didUpdateConfig(Navigator oldConfig) { + if (oldConfig.observer != config.observer) { + oldConfig.observer?._navigator = null; + assert(config.observer == null || config.observer.navigator == null); + config.observer?._navigator = this; + } + } + + void dispose() { + config.observer?._navigator = null; + super.dispose(); + } + bool get hasPreviousRoute => _modal.length > 1; OverlayState get overlay => _overlayKey.currentState; @@ -75,11 +99,7 @@ class NavigatorState extends State { return null; } - Route get currentRoute => _ephemeral.isNotEmpty ? _ephemeral.last : _modal.last; - - Route _removeCurrentRoute() { - return _ephemeral.isNotEmpty ? _ephemeral.removeLast() : _modal.removeLast(); - } + Route get currentRoute => _ephemeral.isNotEmpty ? _ephemeral.last : _modal.isNotEmpty ? _modal.last : null; void pushNamed(String name, { Set mostValuableKeys }) { assert(name != null); @@ -90,9 +110,10 @@ class NavigatorState extends State { push(config.onGenerateRoute(settings) ?? config.onUnknownRoute(settings)); } - void push(Route route) { + void push(Route route, { Set mostValuableKeys }) { _popAllEphemeralRoutes(); route.didPush(overlay, _currentOverlay); + config.observer?.didPushModal(route); _modal.add(route); } @@ -110,7 +131,13 @@ class NavigatorState extends State { } void pop([dynamic result]) { - _removeCurrentRoute().didPop(result); + if (_ephemeral.isNotEmpty) { + _ephemeral.removeLast().didPop(result); + } else { + Route route = _modal.removeLast(); + route.didPop(result); + config.observer?.didPopModal(route); + } } Widget build(BuildContext context) { diff --git a/packages/flutter/lib/src/widgets/page.dart b/packages/flutter/lib/src/widgets/page.dart deleted file mode 100644 index 8833778e8f2..00000000000 --- a/packages/flutter/lib/src/widgets/page.dart +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter/animation.dart'; - -import 'basic.dart'; -import 'framework.dart'; -import 'modal_barrier.dart'; -import 'navigator.dart'; -import 'page_storage.dart'; -import 'transitions.dart'; - -class _PageTransition extends TransitionWithChild { - _PageTransition({ - Key key, - PerformanceView performance, - Widget child - }) : super(key: key, - performance: performance, - child: child); - - final AnimatedValue _position = - new AnimatedValue(const Point(0.0, 75.0), end: Point.origin, curve: Curves.easeOut); - - final AnimatedValue _opacity = - new AnimatedValue(0.0, end: 1.0, curve: Curves.easeOut); - - Widget buildWithChild(BuildContext context, Widget child) { - performance.updateVariable(_position); - performance.updateVariable(_opacity); - Matrix4 transform = new Matrix4.identity() - ..translate(_position.value.x, _position.value.y); - return new Transform( - transform: transform, - child: new Opacity( - opacity: _opacity.value, - child: child - ) - ); - } -} - -class _Page extends StatefulComponent { - _Page({ - Key key, - this.route - }) : super(key: key); - - final PageRoute route; - - _PageState createState() => new _PageState(); -} - -class _PageState extends State<_Page> { - final GlobalKey _subtreeKey = new GlobalKey(); - - Widget build(BuildContext context) { - if (config.route._offstage) { - return new OffStage( - child: new PageStorage( - key: _subtreeKey, - bucket: config.route._storageBucket, - child: _invokeBuilder() - ) - ); - } - return new _PageTransition( - performance: config.route.performance, - child: new PageStorage( - key: _subtreeKey, - bucket: config.route._storageBucket, - child: _invokeBuilder() - ) - ); - } - - Widget _invokeBuilder() { - Widget result = config.route.builder(context); - assert(() { - if (result == null) - debugPrint('The builder for route \'${config.route.name}\' returned null. Route builders must never return null.'); - assert(result != null && 'A route builder returned null. See the previous log message for details.' is String); - return true; - }); - return result; - } -} - -class PageRoute extends ModalRoute { - PageRoute({ - this.builder, - this.settings: const NamedRouteSettings() - }) { - assert(builder != null); - assert(opaque); - } - - final WidgetBuilder builder; - final NamedRouteSettings settings; - - final GlobalKey<_PageState> pageKey = new GlobalKey<_PageState>(); - - bool get opaque => true; - - String get name => settings.name; - Duration get transitionDuration => const Duration(milliseconds: 150); - Widget buildModalWidget(BuildContext context) => new _Page(key: pageKey, route: this); - - final PageStorageBucket _storageBucket = new PageStorageBucket(); - - bool get offstage => _offstage; - bool _offstage = false; - void set offstage (bool value) { - if (_offstage == value) - return; - _offstage = value; - pageKey.currentState?.setState(() { }); - } - - String get debugLabel => '${super.debugLabel}($name)'; -} diff --git a/packages/flutter/lib/src/widgets/routes.dart b/packages/flutter/lib/src/widgets/routes.dart index 0cff051a5c4..d43d1210847 100644 --- a/packages/flutter/lib/src/widgets/routes.dart +++ b/packages/flutter/lib/src/widgets/routes.dart @@ -7,9 +7,13 @@ import 'dart:async'; import 'package:flutter/animation.dart'; import 'basic.dart'; +import 'focus.dart'; import 'framework.dart'; +import 'modal_barrier.dart'; import 'navigator.dart'; import 'overlay.dart'; +import 'page_storage.dart'; +import 'status_transitions.dart'; class StateRoute extends Route { StateRoute({ this.onPop }); @@ -29,7 +33,7 @@ class OverlayRoute extends Route { List get builders => const []; List get overlayEntries => _overlayEntries; - final List _overlayEntries = new List(); + final List _overlayEntries = []; void didPush(OverlayState overlay, OverlayEntry insertionPoint) { for (WidgetBuilder builder in builders) { @@ -99,3 +103,128 @@ abstract class TransitionRoute extends OverlayRoute { String get debugLabel => '$runtimeType'; String toString() => '$runtimeType(performance: $_performance)'; } + +class _ModalScope extends StatusTransitionComponent { + _ModalScope({ + Key key, + this.subtreeKey, + this.storageBucket, + PerformanceView performance, + this.route + }) : super(key: key, performance: performance); + + final GlobalKey subtreeKey; + final PageStorageBucket storageBucket; + final ModalRoute route; + + Widget build(BuildContext context) { + Widget contents = new PageStorage( + key: subtreeKey, + bucket: storageBucket, + child: route.buildPage(context) + ); + if (route.offstage) { + contents = new OffStage(child: contents); + } else { + contents = new Focus( + key: new GlobalObjectKey(route), + child: new IgnorePointer( + ignoring: performance.status == PerformanceStatus.reverse, + child: route.buildTransition(context, performance, contents) + ) + ); + } + ModalPosition position = route.position; + if (position == null) + return contents; + return new Positioned( + top: position.top, + right: position.right, + bottom: position.bottom, + left: position.left, + child: contents + ); + } +} + +class ModalPosition { + const ModalPosition({ this.top, this.right, this.bottom, this.left }); + final double top; + final double right; + final double bottom; + final double left; +} + +abstract class ModalRoute extends TransitionRoute { + ModalRoute({ + Completer completer, + this.settings: const NamedRouteSettings() + }) : super(completer: completer); + + final NamedRouteSettings settings; + + + // The API for subclasses to override - used by _ModalScope + + ModalPosition get position => null; + Widget buildPage(BuildContext context); + Widget buildTransition(BuildContext context, PerformanceView performance, Widget child) { + return child; + } + + // The API for subclasses to override - used by this class + + Color get barrierColor => kTransparent; + + + // The API for _ModalScope and HeroController + + bool get offstage => _offstage; + bool _offstage = false; + void set offstage (bool value) { + if (_offstage == value) + return; + _offstage = value; + _scopeKey.currentState?.setState(() { + // _offstage is the value we're setting, but since there might not be a + // state, we set it outside of this callback (which will only be called if + // there's a state currently built). + // _scopeKey is the key for the _ModalScope built in _buildModalScope(). + // When we mark that state dirty, it'll rebuild itself, and use our + // offstage (via their config.route.offstage) when building. + }); + } + + BuildContext get subtreeContext => _subtreeKey.currentContext; + + + // Internals + + final GlobalKey _scopeKey = new GlobalKey(); + final GlobalKey _subtreeKey = new GlobalKey(); + final PageStorageBucket _storageBucket = new PageStorageBucket(); + + Widget _buildModalBarrier(BuildContext context) { + return new AnimatedModalBarrier( + color: new AnimatedColorValue(kTransparent, end: barrierColor, curve: Curves.ease), + performance: performance, + dismissable: false + ); + } + + Widget _buildModalScope(BuildContext context) { + return new _ModalScope( + key: _scopeKey, + subtreeKey: _subtreeKey, + storageBucket: _storageBucket, + performance: performance, + route: this + ); + } + + List get builders => [ + _buildModalBarrier, + _buildModalScope + ]; + +} diff --git a/packages/flutter/lib/src/widgets/status_transitions.dart b/packages/flutter/lib/src/widgets/status_transitions.dart index 8b3fe3ae1c4..8af8c307a42 100644 --- a/packages/flutter/lib/src/widgets/status_transitions.dart +++ b/packages/flutter/lib/src/widgets/status_transitions.dart @@ -18,10 +18,10 @@ abstract class StatusTransitionComponent extends StatefulComponent { Widget build(BuildContext context); - _StatusTransitionState createState() => new _StatusTransitionState(); + StatusTransitionState createState() => new StatusTransitionState(); } -class _StatusTransitionState extends State { +class StatusTransitionState extends State { void initState() { super.initState(); config.performance.addStatusListener(_performanceStatusChanged); diff --git a/packages/flutter/lib/widgets.dart b/packages/flutter/lib/widgets.dart index da9c32063b7..4c0db2c052c 100644 --- a/packages/flutter/lib/widgets.dart +++ b/packages/flutter/lib/widgets.dart @@ -27,7 +27,6 @@ export 'src/widgets/modal_barrier.dart'; export 'src/widgets/navigator.dart'; export 'src/widgets/overlay.dart'; export 'src/widgets/page_storage.dart'; -export 'src/widgets/page.dart'; export 'src/widgets/placeholder.dart'; export 'src/widgets/routes.dart'; export 'src/widgets/scrollable.dart'; diff --git a/packages/unit/test/widget/bottom_sheet_test.dart b/packages/unit/test/widget/bottom_sheet_test.dart index 92113964d5b..9448fe6577c 100644 --- a/packages/unit/test/widget/bottom_sheet_test.dart +++ b/packages/unit/test/widget/bottom_sheet_test.dart @@ -37,8 +37,8 @@ void main() { // Tap on the the bottom sheet itself to dismiss it tester.tap(tester.findText('BottomSheet')); tester.pump(); // bottom sheet dismiss animation starts - tester.pump(new Duration(seconds: 1)); // animation done - tester.pump(new Duration(seconds: 1)); // rebuild frame + tester.pump(new Duration(seconds: 1)); // last frame of animation (sheet is entirely off-screen, but still present) + tester.pump(new Duration(seconds: 1)); // frame after the animation (sheet has been removed) expect(showBottomSheetThenCalled, isTrue); expect(tester.findText('BottomSheet'), isNull); diff --git a/packages/unit/test/widget/remember_scroll_position_test.dart b/packages/unit/test/widget/remember_scroll_position_test.dart index 904ba7123e9..341adc21976 100644 --- a/packages/unit/test/widget/remember_scroll_position_test.dart +++ b/packages/unit/test/widget/remember_scroll_position_test.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:flutter/animation.dart'; -import 'package:flutter/widgets.dart'; +import 'package:flutter/material.dart'; import 'package:test/test.dart'; import 'widget_tester.dart'; @@ -36,9 +36,9 @@ void main() { key: navigatorKey, onGenerateRoute: (NamedRouteSettings settings) { if (settings.name == '/') - return new PageRoute(builder: (_) => new Container(child: new ThePositiveNumbers())); + return new MaterialPageRoute(builder: (_) => new Container(child: new ThePositiveNumbers())); else if (settings.name == '/second') - return new PageRoute(builder: (_) => new Container(child: new ThePositiveNumbers())); + return new MaterialPageRoute(builder: (_) => new Container(child: new ThePositiveNumbers())); return null; } ));