mirror of
https://github.com/flutter/flutter
synced 2024-10-14 04:02:56 +00:00
NavigatorTransaction
To make it easier to avoid pushing twice in one frame, provide a transaction mechanism for the navigator.
This commit is contained in:
parent
97cca4d47b
commit
f9ea1ce815
|
@ -60,7 +60,7 @@ class FeedFragmentState extends State<FeedFragment> {
|
|||
setState(() {
|
||||
_fitnessMode = value;
|
||||
});
|
||||
Navigator.of(context).pop();
|
||||
Navigator.pop(context);
|
||||
}
|
||||
|
||||
void _showDrawer() {
|
||||
|
@ -91,8 +91,7 @@ class FeedFragmentState extends State<FeedFragment> {
|
|||
}
|
||||
|
||||
void _handleShowSettings() {
|
||||
Navigator.of(context)..pop()
|
||||
..pushNamed('/settings');
|
||||
Navigator.popAndPushNamed(context, '/settings');
|
||||
}
|
||||
|
||||
// TODO(jackson): We should be localizing
|
||||
|
@ -190,7 +189,7 @@ class FeedFragmentState extends State<FeedFragment> {
|
|||
void _handleActionButtonPressed() {
|
||||
showDialog(context: context, child: new AddItemDialog()).then((routeName) {
|
||||
if (routeName != null)
|
||||
Navigator.of(context).pushNamed(routeName);
|
||||
Navigator.pushNamed(context, routeName);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -249,13 +248,13 @@ class AddItemDialogState extends State<AddItemDialog> {
|
|||
new FlatButton(
|
||||
child: new Text('CANCEL'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.pop(context);
|
||||
}
|
||||
),
|
||||
new FlatButton(
|
||||
child: new Text('ADD'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(_addItemRoute);
|
||||
Navigator.pop(context, _addItemRoute);
|
||||
}
|
||||
),
|
||||
]
|
||||
|
|
|
@ -55,14 +55,15 @@ class MealFragmentState extends State<MealFragment> {
|
|||
|
||||
void _handleSave() {
|
||||
config.onCreated(new Meal(when: new DateTime.now(), description: _description));
|
||||
Navigator.of(context).pop();
|
||||
Navigator.pop(context);
|
||||
}
|
||||
|
||||
Widget buildToolBar() {
|
||||
return new ToolBar(
|
||||
left: new IconButton(
|
||||
icon: "navigation/close",
|
||||
onPressed: Navigator.of(context).pop),
|
||||
onPressed: () => Navigator.pop(context)
|
||||
),
|
||||
center: new Text('New Meal'),
|
||||
right: <Widget>[
|
||||
// TODO(abarth): Should this be a FlatButton?
|
||||
|
|
|
@ -77,14 +77,15 @@ class MeasurementFragmentState extends State<MeasurementFragment> {
|
|||
));
|
||||
}
|
||||
config.onCreated(new Measurement(when: _when, weight: parsedWeight));
|
||||
Navigator.of(context).pop();
|
||||
Navigator.pop(context);
|
||||
}
|
||||
|
||||
Widget buildToolBar() {
|
||||
return new ToolBar(
|
||||
left: new IconButton(
|
||||
icon: "navigation/close",
|
||||
onPressed: Navigator.of(context).pop),
|
||||
onPressed: () => Navigator.pop(context)
|
||||
),
|
||||
center: new Text('New Measurement'),
|
||||
right: <Widget>[
|
||||
// TODO(abarth): Should this be a FlatButton?
|
||||
|
|
|
@ -28,7 +28,7 @@ class SettingsFragmentState extends State<SettingsFragment> {
|
|||
return new ToolBar(
|
||||
left: new IconButton(
|
||||
icon: "navigation/arrow_back",
|
||||
onPressed: () => Navigator.of(context).pop()
|
||||
onPressed: () => Navigator.pop(context)
|
||||
),
|
||||
center: new Text('Settings')
|
||||
);
|
||||
|
@ -47,7 +47,7 @@ class SettingsFragmentState extends State<SettingsFragment> {
|
|||
void _handleGoalWeightChanged(String goalWeight) {
|
||||
// TODO(jackson): Looking for null characters to detect enter key is a hack
|
||||
if (goalWeight.endsWith("\u{0}")) {
|
||||
Navigator.of(context).pop(double.parse(goalWeight.replaceAll("\u{0}", "")));
|
||||
Navigator.pop(context, double.parse(goalWeight.replaceAll("\u{0}", "")));
|
||||
} else {
|
||||
setState(() {
|
||||
try {
|
||||
|
@ -74,13 +74,13 @@ class SettingsFragmentState extends State<SettingsFragment> {
|
|||
new FlatButton(
|
||||
child: new Text('CANCEL'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.pop(context);
|
||||
}
|
||||
),
|
||||
new FlatButton(
|
||||
child: new Text('SAVE'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(_goalWeight);
|
||||
Navigator.pop(context, _goalWeight);
|
||||
}
|
||||
),
|
||||
]
|
||||
|
|
|
@ -21,7 +21,7 @@ class GalleryPage extends StatelessComponent {
|
|||
for (WidgetDemo demo in demos) {
|
||||
items.add(new DrawerItem(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pushNamed(demo.routeName);
|
||||
Navigator.pushNamed(context, demo.routeName);
|
||||
},
|
||||
child: new Text(demo.title)
|
||||
));
|
||||
|
|
|
@ -41,7 +41,7 @@ class StockHomeState extends State<StockHome> {
|
|||
}
|
||||
|
||||
void _handleSearchEnd() {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.pop(context);
|
||||
}
|
||||
|
||||
void _handleSearchQueryChanged(String query) {
|
||||
|
@ -92,13 +92,13 @@ class StockHomeState extends State<StockHome> {
|
|||
new FlatButton(
|
||||
child: new Text('USE IT'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(false);
|
||||
Navigator.pop(context, false);
|
||||
}
|
||||
),
|
||||
new FlatButton(
|
||||
child: new Text('OH WELL'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(false);
|
||||
Navigator.pop(context, false);
|
||||
}
|
||||
),
|
||||
]
|
||||
|
@ -142,8 +142,7 @@ class StockHomeState extends State<StockHome> {
|
|||
}
|
||||
|
||||
void _handleShowSettings() {
|
||||
Navigator.of(context)..pop()
|
||||
..pushNamed('/settings');
|
||||
Navigator.popAndPushNamed(context, '/settings');
|
||||
}
|
||||
|
||||
Widget buildToolBar() {
|
||||
|
@ -207,7 +206,7 @@ class StockHomeState extends State<StockHome> {
|
|||
onOpen: (Stock stock, Key arrowKey) {
|
||||
Set<Key> mostValuableKeys = new Set<Key>();
|
||||
mostValuableKeys.add(arrowKey);
|
||||
Navigator.of(context).pushNamed('/stock/${stock.symbol}', mostValuableKeys: mostValuableKeys);
|
||||
Navigator.pushNamed(context, '/stock/${stock.symbol}', mostValuableKeys: mostValuableKeys);
|
||||
},
|
||||
onShow: (Stock stock, Key arrowKey) {
|
||||
scaffoldKey.currentState.showBottomSheet((BuildContext context) => new StockSymbolBottomSheet(stock: stock));
|
||||
|
|
|
@ -23,10 +23,9 @@ Future showStockMenu({BuildContext context, bool autorefresh, ValueChanged<bool>
|
|||
new Checkbox(
|
||||
value: autorefresh,
|
||||
onChanged: (bool value) {
|
||||
Navigator.of(context).setState(() {
|
||||
autorefresh = value;
|
||||
});
|
||||
Navigator.of(context).pop(_MenuItems.autorefreshCheckbox);
|
||||
// TODO(ianh): https://github.com/flutter/flutter/issues/187
|
||||
autorefresh = value;
|
||||
Navigator.pop(context, _MenuItems.autorefreshCheckbox);
|
||||
}
|
||||
)
|
||||
]
|
||||
|
@ -43,9 +42,8 @@ Future showStockMenu({BuildContext context, bool autorefresh, ValueChanged<bool>
|
|||
]
|
||||
)) {
|
||||
case _MenuItems.autorefresh:
|
||||
Navigator.of(context).setState(() {
|
||||
autorefresh = !autorefresh;
|
||||
});
|
||||
// TODO(ianh): https://github.com/flutter/flutter/issues/187
|
||||
autorefresh = !autorefresh;
|
||||
continue autorefreshNotify;
|
||||
autorefreshNotify:
|
||||
case _MenuItems.autorefreshCheckbox:
|
||||
|
@ -75,7 +73,7 @@ Future showStockMenu({BuildContext context, bool autorefresh, ValueChanged<bool>
|
|||
new FlatButton(
|
||||
child: new Text('OH WELL'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(false);
|
||||
Navigator.pop(context, false);
|
||||
}
|
||||
),
|
||||
]
|
||||
|
|
|
@ -44,13 +44,13 @@ class StockSettingsState extends State<StockSettings> {
|
|||
new FlatButton(
|
||||
child: new Text('NO THANKS'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(false);
|
||||
Navigator.pop(context, false);
|
||||
}
|
||||
),
|
||||
new FlatButton(
|
||||
child: new Text('AGREE'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(true);
|
||||
Navigator.pop(context, true);
|
||||
}
|
||||
),
|
||||
]
|
||||
|
@ -72,7 +72,7 @@ class StockSettingsState extends State<StockSettings> {
|
|||
return new ToolBar(
|
||||
left: new IconButton(
|
||||
icon: 'navigation/arrow_back',
|
||||
onPressed: () => Navigator.of(context).pop()
|
||||
onPressed: () => Navigator.pop(context)
|
||||
),
|
||||
center: new Text('Settings')
|
||||
);
|
||||
|
|
|
@ -58,7 +58,7 @@ class StockSymbolPage extends StatelessComponent {
|
|||
left: new IconButton(
|
||||
icon: 'navigation/arrow_back',
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.pop(context);
|
||||
}
|
||||
),
|
||||
center: new Text(stock.name)
|
||||
|
|
|
@ -15,11 +15,11 @@ class Home extends StatelessComponent {
|
|||
),
|
||||
new RaisedButton(
|
||||
child: new Text('GO SHOPPING'),
|
||||
onPressed: () => Navigator.of(context).pushNamed('/shopping')
|
||||
onPressed: () => Navigator.pushNamed(context, '/shopping')
|
||||
),
|
||||
new RaisedButton(
|
||||
child: new Text('START ADVENTURE'),
|
||||
onPressed: () => Navigator.of(context).pushNamed('/adventure')
|
||||
onPressed: () => Navigator.pushNamed(context, '/adventure')
|
||||
)
|
||||
],
|
||||
padding: const EdgeDims.all(30.0)
|
||||
|
@ -41,11 +41,11 @@ class Shopping extends StatelessComponent {
|
|||
),
|
||||
new RaisedButton(
|
||||
child: new Text('RETURN HOME'),
|
||||
onPressed: () => Navigator.of(context).pop()
|
||||
onPressed: () => Navigator.pop(context)
|
||||
),
|
||||
new RaisedButton(
|
||||
child: new Text('GO TO DUNGEON'),
|
||||
onPressed: () => Navigator.of(context).pushNamed('/adventure')
|
||||
onPressed: () => Navigator.pushNamed(context, '/adventure')
|
||||
)
|
||||
],
|
||||
padding: const EdgeDims.all(30.0)
|
||||
|
@ -67,7 +67,7 @@ class Adventure extends StatelessComponent {
|
|||
),
|
||||
new RaisedButton(
|
||||
child: new Text('RUN!!!'),
|
||||
onPressed: () => Navigator.of(context).pop()
|
||||
onPressed: () => Navigator.pop(context)
|
||||
)
|
||||
],
|
||||
padding: const EdgeDims.all(30.0)
|
||||
|
|
|
@ -119,7 +119,7 @@ class _ModalBottomSheetState extends State<_ModalBottomSheet> {
|
|||
|
||||
Widget build(BuildContext context) {
|
||||
return new GestureDetector(
|
||||
onTap: () { Navigator.of(context).pop(); },
|
||||
onTap: () => Navigator.pop(context),
|
||||
child: new BuilderTransition(
|
||||
performance: config.route.performance,
|
||||
variables: <AnimatedValue<double>>[_layout.childTop],
|
||||
|
@ -130,7 +130,7 @@ class _ModalBottomSheetState extends State<_ModalBottomSheet> {
|
|||
token: _layout.childTop.value,
|
||||
child: new BottomSheet(
|
||||
performance: config.route.performance,
|
||||
onClosing: () { Navigator.of(context).pop(); },
|
||||
onClosing: () => Navigator.pop(context),
|
||||
childHeight: _layout.childTop.end,
|
||||
builder: config.route.builder
|
||||
)
|
||||
|
@ -167,7 +167,7 @@ Future showModalBottomSheet({ BuildContext context, WidgetBuilder builder }) {
|
|||
assert(context != null);
|
||||
assert(builder != null);
|
||||
final Completer completer = new Completer();
|
||||
Navigator.of(context).push(new _ModalBottomSheetRoute(
|
||||
Navigator.push(context, new _ModalBottomSheetRoute(
|
||||
completer: completer,
|
||||
builder: builder
|
||||
));
|
||||
|
|
|
@ -40,11 +40,11 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
|
|||
}
|
||||
|
||||
void _handleCancel() {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.pop(context);
|
||||
}
|
||||
|
||||
void _handleOk() {
|
||||
Navigator.of(context).pop(_selectedDate);
|
||||
Navigator.pop(context, _selectedDate);
|
||||
}
|
||||
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
@ -140,6 +140,6 @@ class _DialogRoute<T> extends PopupRoute<T> {
|
|||
|
||||
Future showDialog({ BuildContext context, Widget child }) {
|
||||
Completer completer = new Completer();
|
||||
Navigator.of(context).push(new _DialogRoute(completer: completer, child: child));
|
||||
Navigator.push(context, new _DialogRoute(completer: completer, child: child));
|
||||
return completer.future;
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ class _DrawerRoute extends OverlayRoute {
|
|||
_state = _DrawerState.closed;
|
||||
switch (previousState) {
|
||||
case _DrawerState.showing:
|
||||
Navigator.of(context).pop();
|
||||
Navigator.pop(context);
|
||||
break;
|
||||
case _DrawerState.popped:
|
||||
finished();
|
||||
|
@ -220,5 +220,5 @@ class _DrawerControllerState extends State<_DrawerController> {
|
|||
}
|
||||
|
||||
void showDrawer({ BuildContext context, Widget child, int elevation: 16 }) {
|
||||
Navigator.of(context).push(new _DrawerRoute(child: child, elevation: elevation));
|
||||
Navigator.push(context, new _DrawerRoute(child: child, elevation: elevation));
|
||||
}
|
||||
|
|
|
@ -93,9 +93,7 @@ class _DropDownMenu<T> extends StatusTransitionComponent {
|
|||
padding: _kMenuHorizontalPadding,
|
||||
child: route.items[itemIndex]
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.of(context).pop(route.items[itemIndex].value);
|
||||
}
|
||||
onTap: () => Navigator.pop(context, route.items[itemIndex].value)
|
||||
)
|
||||
));
|
||||
}
|
||||
|
@ -117,7 +115,7 @@ class _DropDownMenu<T> extends StatusTransitionComponent {
|
|||
reverseCurve: const Interval(0.0, 0.001)
|
||||
);
|
||||
|
||||
final RenderBox renderBox = Navigator.of(context).context.findRenderObject();
|
||||
final RenderBox renderBox = route.navigator.context.findRenderObject();
|
||||
final Size navigatorSize = renderBox.size;
|
||||
final RelativeRect menuRect = new RelativeRect.fromSize(route.rect, navigatorSize);
|
||||
|
||||
|
@ -216,7 +214,7 @@ class DropDownButton<T> extends StatelessComponent {
|
|||
final RenderBox renderBox = indexedStackKey.currentContext.findRenderObject();
|
||||
final Rect rect = renderBox.localToGlobal(Point.origin) & renderBox.size;
|
||||
final Completer completer = new Completer<T>();
|
||||
Navigator.of(context).push(new _DropDownRoute<T>(
|
||||
Navigator.push(context, new _DropDownRoute<T>(
|
||||
completer: completer,
|
||||
items: items,
|
||||
selectedIndex: selectedIndex,
|
||||
|
|
|
@ -81,8 +81,10 @@ class _MaterialAppState extends State<MaterialApp> implements BindingObserver {
|
|||
assert(mounted);
|
||||
NavigatorState navigator = _navigator.currentState;
|
||||
assert(navigator != null);
|
||||
if (!navigator.pop())
|
||||
activity.finishCurrentActivity();
|
||||
navigator.openTransaction((NavigatorTransaction transaction) {
|
||||
if (!transaction.pop())
|
||||
activity.finishCurrentActivity();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ class _PopupMenu<T> extends StatelessComponent {
|
|||
performance: route.performance,
|
||||
opacity: new AnimatedValue<double>(0.0, end: 1.0, curve: new Interval(start, end)),
|
||||
child: new InkWell(
|
||||
onTap: () { Navigator.of(context).pop(route.items[i].value); },
|
||||
onTap: () => Navigator.pop(context, route.items[i].value),
|
||||
child: route.items[i]
|
||||
))
|
||||
);
|
||||
|
@ -114,7 +114,7 @@ class _PopupMenuRoute<T> extends PopupRoute<T> {
|
|||
|
||||
Future showMenu({ BuildContext context, ModalPosition position, List<PopupMenuItem> items, int elevation: 8 }) {
|
||||
Completer completer = new Completer();
|
||||
Navigator.of(context).push(new _PopupMenuRoute(
|
||||
Navigator.push(context, new _PopupMenuRoute(
|
||||
completer: completer,
|
||||
position: position,
|
||||
items: items,
|
||||
|
|
|
@ -36,11 +36,11 @@ class _TimePickerDialogState extends State<_TimePickerDialog> {
|
|||
}
|
||||
|
||||
void _handleCancel() {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.pop(context);
|
||||
}
|
||||
|
||||
void _handleOk() {
|
||||
Navigator.of(context).pop(_selectedTime);
|
||||
Navigator.pop(context, _selectedTime);
|
||||
}
|
||||
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
@ -11,7 +11,6 @@ import 'package:flutter/services.dart';
|
|||
import 'basic.dart';
|
||||
import 'binding.dart';
|
||||
import 'framework.dart';
|
||||
import 'navigator.dart';
|
||||
import 'overlay.dart';
|
||||
|
||||
typedef bool DragTargetWillAccept<T>(T data);
|
||||
|
@ -165,7 +164,7 @@ class _DraggableState<T> extends State<DraggableBase<T>> implements GestureArena
|
|||
new _DragAvatar<T>(
|
||||
pointer: pointer,
|
||||
router: router,
|
||||
overlay: Navigator.of(context).overlay,
|
||||
overlay: Overlay.of(context),
|
||||
data: config.data,
|
||||
initialPosition: position,
|
||||
dragStartPoint: dragStartPoint,
|
||||
|
|
|
@ -23,7 +23,7 @@ class ModalBarrier extends StatelessComponent {
|
|||
return new Listener(
|
||||
onPointerDown: (_) {
|
||||
if (dismissable)
|
||||
Navigator.of(context).pop();
|
||||
Navigator.pop(context);
|
||||
},
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: new ConstrainedBox(
|
||||
|
|
|
@ -14,13 +14,13 @@ abstract class Route<T> {
|
|||
|
||||
/// Called when the route is inserted into the navigator.
|
||||
///
|
||||
/// Use this to populate overlayEntries and add them to the overlay.
|
||||
/// (The reason the Route is responsible for doing this, rather than the
|
||||
/// Navigator, is that the Route will be responsible for _removing_ the
|
||||
/// entries and this way it's symmetric.
|
||||
/// Use this to populate overlayEntries and add them to the overlay
|
||||
/// (accessible as navigator.overlay). (The reason the Route is responsible
|
||||
/// for doing this, rather than the Navigator, is that the Route will be
|
||||
/// responsible for _removing_ the entries and this way it's symmetric.)
|
||||
///
|
||||
/// The overlay argument will be null if this is the first route inserted.
|
||||
void install(OverlayState overlay, OverlayEntry insertionPoint) { }
|
||||
void install(OverlayEntry insertionPoint) { }
|
||||
|
||||
/// Called after install() when the route is pushed onto the navigator.
|
||||
void didPush() { }
|
||||
|
@ -81,6 +81,7 @@ class NamedRouteSettings {
|
|||
}
|
||||
|
||||
typedef Route RouteFactory(NamedRouteSettings settings);
|
||||
typedef void NavigatorTransactionCallback(NavigatorTransaction transaction);
|
||||
|
||||
class NavigatorObserver {
|
||||
/// The navigator that the observer is observing, if any.
|
||||
|
@ -108,7 +109,37 @@ class Navigator extends StatefulComponent {
|
|||
|
||||
static const String defaultRouteName = '/';
|
||||
|
||||
static NavigatorState of(BuildContext context) => context.ancestorStateOfType(NavigatorState);
|
||||
static void pushNamed(BuildContext context, String routeName, { Set<Key> mostValuableKeys }) {
|
||||
openTransaction(context, (NavigatorTransaction transaction) {
|
||||
transaction.pushNamed(routeName, mostValuableKeys: mostValuableKeys);
|
||||
});
|
||||
}
|
||||
|
||||
static void push(BuildContext context, Route route, { Set<Key> mostValuableKeys }) {
|
||||
openTransaction(context, (NavigatorTransaction transaction) {
|
||||
transaction.push(route, mostValuableKeys: mostValuableKeys);
|
||||
});
|
||||
}
|
||||
|
||||
static bool pop(BuildContext context, [ dynamic result ]) {
|
||||
bool returnValue;
|
||||
openTransaction(context, (NavigatorTransaction transaction) {
|
||||
returnValue = transaction.pop(result);
|
||||
});
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
static void popAndPushNamed(BuildContext context, String routeName, { Set<Key> mostValuableKeys }) {
|
||||
openTransaction(context, (NavigatorTransaction transaction) {
|
||||
transaction.pop();
|
||||
transaction.pushNamed(routeName, mostValuableKeys: mostValuableKeys);
|
||||
});
|
||||
}
|
||||
|
||||
static void openTransaction(BuildContext context, NavigatorTransactionCallback callback) {
|
||||
NavigatorState navigator = context.ancestorStateOfType(NavigatorState);
|
||||
navigator.openTransaction(callback);
|
||||
}
|
||||
|
||||
NavigatorState createState() => new NavigatorState();
|
||||
}
|
||||
|
@ -121,7 +152,7 @@ class NavigatorState extends State<Navigator> {
|
|||
super.initState();
|
||||
assert(config.observer == null || config.observer.navigator == null);
|
||||
config.observer?._navigator = this;
|
||||
push(config.onGenerateRoute(new NamedRouteSettings(
|
||||
_push(config.onGenerateRoute(new NamedRouteSettings(
|
||||
name: config.initialRoute ?? Navigator.defaultRouteName
|
||||
)));
|
||||
}
|
||||
|
@ -146,9 +177,10 @@ class NavigatorState extends State<Navigator> {
|
|||
assert(() { _debugLocked = false; return true; });
|
||||
}
|
||||
|
||||
// Used by Routes and NavigatorObservers
|
||||
OverlayState get overlay => _overlayKey.currentState;
|
||||
|
||||
OverlayEntry get _currentOverlay {
|
||||
OverlayEntry get _currentOverlayEntry {
|
||||
for (Route route in _history.reversed) {
|
||||
if (route.overlayEntries.isNotEmpty)
|
||||
return route.overlayEntries.last;
|
||||
|
@ -158,17 +190,17 @@ class NavigatorState extends State<Navigator> {
|
|||
|
||||
bool _debugLocked = false; // used to prevent re-entrant calls to push, pop, and friends
|
||||
|
||||
void pushNamed(String name, { Set<Key> mostValuableKeys }) {
|
||||
void _pushNamed(String name, { Set<Key> mostValuableKeys }) {
|
||||
assert(!_debugLocked);
|
||||
assert(name != null);
|
||||
NamedRouteSettings settings = new NamedRouteSettings(
|
||||
name: name,
|
||||
mostValuableKeys: mostValuableKeys
|
||||
);
|
||||
push(config.onGenerateRoute(settings) ?? config.onUnknownRoute(settings));
|
||||
_push(config.onGenerateRoute(settings) ?? config.onUnknownRoute(settings));
|
||||
}
|
||||
|
||||
void push(Route route, { Set<Key> mostValuableKeys }) {
|
||||
void _push(Route route, { Set<Key> mostValuableKeys }) {
|
||||
assert(!_debugLocked);
|
||||
assert(() { _debugLocked = true; return true; });
|
||||
assert(route != null);
|
||||
|
@ -176,7 +208,7 @@ class NavigatorState extends State<Navigator> {
|
|||
setState(() {
|
||||
Route oldRoute = _history.isNotEmpty ? _history.last : null;
|
||||
route._navigator = this;
|
||||
route.install(overlay, _currentOverlay);
|
||||
route.install(_currentOverlayEntry);
|
||||
_history.add(route);
|
||||
route.didPush();
|
||||
if (oldRoute != null)
|
||||
|
@ -186,18 +218,7 @@ class NavigatorState extends State<Navigator> {
|
|||
assert(() { _debugLocked = false; return true; });
|
||||
}
|
||||
|
||||
/// Replaces one given route with another, but does not call didPush/didPop.
|
||||
/// Instead, this calls install() on the new route, then didReplace() on the
|
||||
/// new route passing the old route, then dispose() on the old route.
|
||||
///
|
||||
/// The old route must have overlays, otherwise we won't know where to insert
|
||||
/// the overlays of the new route. The old route must not be currently visible
|
||||
/// (i.e. a later route have overlays that are currently opaque), otherwise
|
||||
/// the replacement would have a jarring effect.
|
||||
///
|
||||
/// It is safe to call this redundantly (replacing a route with itself). Such
|
||||
/// calls are ignored.
|
||||
void replace({ Route oldRoute, Route newRoute }) {
|
||||
void _replace({ Route oldRoute, Route newRoute }) {
|
||||
assert(!_debugLocked);
|
||||
assert(oldRoute != null);
|
||||
assert(newRoute != null);
|
||||
|
@ -213,7 +234,7 @@ class NavigatorState extends State<Navigator> {
|
|||
int index = _history.indexOf(oldRoute);
|
||||
assert(index >= 0);
|
||||
newRoute._navigator = this;
|
||||
newRoute.install(overlay, oldRoute.overlayEntries.last);
|
||||
newRoute.install(oldRoute.overlayEntries.last);
|
||||
_history[index] = newRoute;
|
||||
newRoute.didReplace(oldRoute);
|
||||
if (index > 0)
|
||||
|
@ -224,24 +245,14 @@ class NavigatorState extends State<Navigator> {
|
|||
assert(() { _debugLocked = false; return true; });
|
||||
}
|
||||
|
||||
/// Like replace(), but affects the route before the given anchorRoute rather
|
||||
/// than the anchorRoute itself.
|
||||
///
|
||||
/// If newRoute is already the route before anchorRoute, then the call is
|
||||
/// ignored.
|
||||
///
|
||||
/// The conditions described for [replace()] apply; for instance, the route
|
||||
/// before anchorRoute must have overlays.
|
||||
void replaceRouteBefore({ Route anchorRoute, Route newRoute }) {
|
||||
void _replaceRouteBefore({ Route anchorRoute, Route newRoute }) {
|
||||
assert(anchorRoute != null);
|
||||
assert(anchorRoute._navigator == this);
|
||||
assert(_history.indexOf(anchorRoute) > 0);
|
||||
replace(oldRoute: _history[_history.indexOf(anchorRoute)-1], newRoute: newRoute);
|
||||
_replace(oldRoute: _history[_history.indexOf(anchorRoute)-1], newRoute: newRoute);
|
||||
}
|
||||
|
||||
/// Removes the route prior to the given anchorRoute without notifying
|
||||
/// neighbouring routes or the navigator observer, if any.
|
||||
void removeRouteBefore(Route anchorRoute) {
|
||||
void _removeRouteBefore(Route anchorRoute) {
|
||||
assert(!_debugLocked);
|
||||
assert(() { _debugLocked = true; return true; });
|
||||
assert(anchorRoute._navigator == this);
|
||||
|
@ -258,16 +269,7 @@ class NavigatorState extends State<Navigator> {
|
|||
assert(() { _debugLocked = false; return true; });
|
||||
}
|
||||
|
||||
/// Removes the current route, notifying the observer (if any), and the
|
||||
/// previous routes (using [Route.didPopNext]).
|
||||
///
|
||||
/// The type of the result argument, if provided, must match the type argument
|
||||
/// of the class of the current route. (In practice, this is usually
|
||||
/// "dynamic".)
|
||||
///
|
||||
/// Returns true if a route was popped; returns false if there are no further
|
||||
/// previous routes.
|
||||
bool pop([dynamic result]) {
|
||||
bool _pop([dynamic result]) {
|
||||
assert(!_debugLocked);
|
||||
assert(() { _debugLocked = true; return true; });
|
||||
Route route = _history.last;
|
||||
|
@ -292,20 +294,123 @@ class NavigatorState extends State<Navigator> {
|
|||
return true;
|
||||
}
|
||||
|
||||
/// Calls pop() repeatedly until the given route is the current route.
|
||||
/// If it is already the current route, nothing happens.
|
||||
void popUntil(Route targetRoute) {
|
||||
void _popUntil(Route targetRoute) {
|
||||
assert(_history.contains(targetRoute));
|
||||
while (!targetRoute.isCurrent)
|
||||
pop();
|
||||
_pop();
|
||||
}
|
||||
|
||||
bool _hadTransaction = true;
|
||||
|
||||
bool openTransaction(NavigatorTransactionCallback callback) {
|
||||
assert(callback != null);
|
||||
if (_hadTransaction)
|
||||
return false;
|
||||
_hadTransaction = true;
|
||||
NavigatorTransaction transaction = new NavigatorTransaction._(this);
|
||||
setState(() {
|
||||
callback(transaction);
|
||||
});
|
||||
assert(() { transaction._debugClose(); return true; });
|
||||
return true;
|
||||
}
|
||||
|
||||
Widget build(BuildContext context) {
|
||||
assert(!_debugLocked);
|
||||
assert(_history.isNotEmpty);
|
||||
_hadTransaction = false;
|
||||
return new Overlay(
|
||||
key: _overlayKey,
|
||||
initialEntries: _history.first.overlayEntries
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class NavigatorTransaction {
|
||||
NavigatorTransaction._(this._navigator) {
|
||||
assert(_navigator != null);
|
||||
}
|
||||
NavigatorState _navigator;
|
||||
bool _debugOpen = true;
|
||||
|
||||
/// Invokes the Navigator's onGenerateRoute callback to create a route with
|
||||
/// the given name, then calls [push()] with that route.
|
||||
void pushNamed(String name, { Set<Key> mostValuableKeys }) {
|
||||
assert(_debugOpen);
|
||||
_navigator._pushNamed(name, mostValuableKeys: mostValuableKeys);
|
||||
}
|
||||
|
||||
/// Adds the given route to the Navigator's history, and transitions to it.
|
||||
/// The route will have didPush() called on it; the previous route, if any,
|
||||
/// will have didPushNext() called on it; and the Navigator observer, if any,
|
||||
/// will have didPush() called on it.
|
||||
void push(Route route, { Set<Key> mostValuableKeys }) {
|
||||
assert(_debugOpen);
|
||||
_navigator._push(route, mostValuableKeys: mostValuableKeys);
|
||||
}
|
||||
|
||||
/// Replaces one given route with another, but does not call didPush/didPop.
|
||||
/// Instead, this calls install() on the new route, then didReplace() on the
|
||||
/// new route passing the old route, then dispose() on the old route. The
|
||||
/// navigator is not informed of the replacement.
|
||||
///
|
||||
/// The old route must have overlay entries, otherwise we won't know where to
|
||||
/// insert the entries of the new route. The old route must not be currently
|
||||
/// visible (i.e. a later route have overlay entries that are currently
|
||||
/// opaque), otherwise the replacement would have a jarring effect.
|
||||
///
|
||||
/// It is safe to call this redundantly (replacing a route with itself). Such
|
||||
/// calls are ignored.
|
||||
void replace({ Route oldRoute, Route newRoute }) {
|
||||
assert(_debugOpen);
|
||||
_navigator._replace(oldRoute: oldRoute, newRoute: newRoute);
|
||||
}
|
||||
|
||||
/// Like replace(), but affects the route before the given anchorRoute rather
|
||||
/// than the anchorRoute itself.
|
||||
///
|
||||
/// If newRoute is already the route before anchorRoute, then the call is
|
||||
/// ignored.
|
||||
///
|
||||
/// The conditions described for [replace()] apply; for instance, the route
|
||||
/// before anchorRoute must have overlay entries.
|
||||
void replaceRouteBefore({ Route anchorRoute, Route newRoute }) {
|
||||
assert(_debugOpen);
|
||||
_navigator._replaceRouteBefore(anchorRoute: anchorRoute, newRoute: newRoute);
|
||||
}
|
||||
|
||||
/// Removes the route prior to the given anchorRoute without notifying
|
||||
/// neighbouring routes or the navigator observer, if any.
|
||||
void removeRouteBefore(Route anchorRoute) {
|
||||
assert(_debugOpen);
|
||||
_navigator._removeRouteBefore(anchorRoute);
|
||||
}
|
||||
|
||||
/// Tries to removes the current route, calling its didPop() method. If that
|
||||
/// method returns false, then nothing else happens. Otherwise, the observer
|
||||
/// (if any) is notified using its didPop() method, and the previous route is
|
||||
/// notified using [Route.didPopNext].
|
||||
///
|
||||
/// The type of the result argument, if provided, must match the type argument
|
||||
/// of the class of the current route. (In practice, this is usually
|
||||
/// "dynamic".)
|
||||
///
|
||||
/// Returns true if a route was popped; returns false if there are no further
|
||||
/// previous routes.
|
||||
bool pop([dynamic result]) {
|
||||
assert(_debugOpen);
|
||||
return _navigator._pop(result);
|
||||
}
|
||||
|
||||
/// Calls pop() repeatedly until the given route is the current route.
|
||||
/// If it is already the current route, nothing happens.
|
||||
void popUntil(Route targetRoute) {
|
||||
assert(_debugOpen);
|
||||
_navigator._popUntil(targetRoute);
|
||||
}
|
||||
|
||||
void _debugClose() {
|
||||
assert(_debugOpen);
|
||||
_debugOpen = false;
|
||||
}
|
||||
}
|
|
@ -44,6 +44,8 @@ class Overlay extends StatefulComponent {
|
|||
|
||||
final List<OverlayEntry> initialEntries;
|
||||
|
||||
static OverlayState of(BuildContext context) => context.ancestorStateOfType(OverlayState);
|
||||
|
||||
OverlayState createState() => new OverlayState();
|
||||
}
|
||||
|
||||
|
|
|
@ -23,11 +23,11 @@ abstract class OverlayRoute<T> extends Route<T> {
|
|||
List<OverlayEntry> get overlayEntries => _overlayEntries;
|
||||
final List<OverlayEntry> _overlayEntries = <OverlayEntry>[];
|
||||
|
||||
void install(OverlayState overlay, OverlayEntry insertionPoint) {
|
||||
void install(OverlayEntry insertionPoint) {
|
||||
assert(_overlayEntries.isEmpty);
|
||||
for (WidgetBuilder builder in builders)
|
||||
_overlayEntries.add(new OverlayEntry(builder: builder));
|
||||
overlay?.insertAll(_overlayEntries, above: insertionPoint);
|
||||
navigator.overlay?.insertAll(_overlayEntries, above: insertionPoint);
|
||||
}
|
||||
|
||||
// Subclasses shouldn't call this if they want to delay the finished() call.
|
||||
|
@ -108,9 +108,9 @@ abstract class TransitionRoute<T> extends OverlayRoute<T> {
|
|||
}
|
||||
}
|
||||
|
||||
void install(OverlayState overlay, OverlayEntry insertionPoint) {
|
||||
void install(OverlayEntry insertionPoint) {
|
||||
_performance = createPerformance();
|
||||
super.install(overlay, insertionPoint);
|
||||
super.install(insertionPoint);
|
||||
}
|
||||
|
||||
void didPush() {
|
||||
|
|
|
@ -29,7 +29,7 @@ void main() {
|
|||
expect(tester.findText('drawer'), isNotNull);
|
||||
tester.pump(new Duration(seconds: 1)); // animation done
|
||||
expect(tester.findText('drawer'), isNotNull);
|
||||
Navigator.of(context).pop();
|
||||
Navigator.pop(context);
|
||||
tester.pump(); // drawer should be starting to animate away
|
||||
expect(tester.findText('drawer'), isNotNull);
|
||||
tester.pump(new Duration(seconds: 1)); // animation done
|
||||
|
|
|
@ -15,13 +15,13 @@ final Map<String, RouteBuilder> routes = <String, RouteBuilder>{
|
|||
new Container(height: 100.0, width: 100.0),
|
||||
new Card(child: new Hero(tag: 'a', child: new Container(height: 100.0, width: 100.0, key: firstKey))),
|
||||
new Container(height: 100.0, width: 100.0),
|
||||
new FlatButton(child: new Text('button'), onPressed: () => Navigator.of(args.context).pushNamed('/two')),
|
||||
new FlatButton(child: new Text('button'), onPressed: () => Navigator.pushNamed(args.context, '/two')),
|
||||
]),
|
||||
'/two': (RouteArguments args) => new Block([
|
||||
new Container(height: 150.0, width: 150.0),
|
||||
new Card(child: new Hero(tag: 'a', child: new Container(height: 150.0, width: 150.0, key: secondKey))),
|
||||
new Container(height: 150.0, width: 150.0),
|
||||
new FlatButton(child: new Text('button'), onPressed: () => Navigator.of(args.context).pop()),
|
||||
new FlatButton(child: new Text('button'), onPressed: () => Navigator.pop(args.context)),
|
||||
]),
|
||||
};
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ class FirstComponent extends StatelessComponent {
|
|||
Widget build(BuildContext context) {
|
||||
return new GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamed('/second');
|
||||
Navigator.pushNamed(context, '/second');
|
||||
},
|
||||
child: new Container(
|
||||
decoration: new BoxDecoration(
|
||||
|
@ -29,7 +29,7 @@ class SecondComponent extends StatefulComponent {
|
|||
class SecondComponentState extends State<SecondComponent> {
|
||||
Widget build(BuildContext context) {
|
||||
return new GestureDetector(
|
||||
onTap: Navigator.of(context).pop,
|
||||
onTap: () => Navigator.pop(context),
|
||||
child: new Container(
|
||||
decoration: new BoxDecoration(
|
||||
backgroundColor: new Color(0xFFFF00FF)
|
||||
|
|
|
@ -16,10 +16,11 @@ class TestOverlayRoute extends OverlayRoute {
|
|||
void main() {
|
||||
test('Check onstage/offstage handling around transitions', () {
|
||||
testWidgets((WidgetTester tester) {
|
||||
GlobalKey containerKey = new GlobalKey();
|
||||
GlobalKey containerKey1 = new GlobalKey();
|
||||
GlobalKey containerKey2 = new GlobalKey();
|
||||
final Map<String, RouteBuilder> routes = <String, RouteBuilder>{
|
||||
'/': (_) => new Container(key: containerKey, child: new Text('Home')),
|
||||
'/settings': (_) => new Container(child: new Text('Settings')),
|
||||
'/': (_) => new Container(key: containerKey1, child: new Text('Home')),
|
||||
'/settings': (_) => new Container(key: containerKey2, child: new Text('Settings')),
|
||||
};
|
||||
|
||||
tester.pumpWidget(new MaterialApp(routes: routes));
|
||||
|
@ -28,9 +29,7 @@ void main() {
|
|||
expect(tester.findText('Settings'), isNull);
|
||||
expect(tester.findText('Overlay'), isNull);
|
||||
|
||||
NavigatorState navigator = Navigator.of(containerKey.currentContext);
|
||||
|
||||
navigator.pushNamed('/settings');
|
||||
Navigator.pushNamed(containerKey1.currentContext, '/settings');
|
||||
|
||||
tester.pump();
|
||||
|
||||
|
@ -50,7 +49,7 @@ void main() {
|
|||
expect(tester.findText('Settings'), isOnStage);
|
||||
expect(tester.findText('Overlay'), isNull);
|
||||
|
||||
navigator.push(new TestOverlayRoute());
|
||||
Navigator.push(containerKey2.currentContext, new TestOverlayRoute());
|
||||
|
||||
tester.pump();
|
||||
|
||||
|
@ -64,7 +63,7 @@ void main() {
|
|||
expect(tester.findText('Settings'), isOnStage);
|
||||
expect(tester.findText('Overlay'), isOnStage);
|
||||
|
||||
navigator.pop();
|
||||
Navigator.pop(containerKey2.currentContext);
|
||||
tester.pump();
|
||||
|
||||
expect(tester.findText('Home'), isNull);
|
||||
|
@ -77,7 +76,7 @@ void main() {
|
|||
expect(tester.findText('Settings'), isOnStage);
|
||||
expect(tester.findText('Overlay'), isNull);
|
||||
|
||||
navigator.pop();
|
||||
Navigator.pop(containerKey2.currentContext);
|
||||
tester.pump();
|
||||
|
||||
expect(tester.findText('Home'), isOnStage);
|
||||
|
|
|
@ -74,7 +74,9 @@ void main() {
|
|||
expect(tester.findText('16'), isNull);
|
||||
expect(tester.findText('100'), isNull);
|
||||
|
||||
navigatorKey.currentState.pushNamed('/second');
|
||||
navigatorKey.currentState.openTransaction(
|
||||
(NavigatorTransaction transaction) => transaction.pushNamed('/second')
|
||||
);
|
||||
tester.pump(); // navigating always takes two frames
|
||||
tester.pump(new Duration(seconds: 1));
|
||||
|
||||
|
@ -89,7 +91,9 @@ void main() {
|
|||
expect(tester.findText('10'), isNull);
|
||||
expect(tester.findText('100'), isNull);
|
||||
|
||||
navigatorKey.currentState.pop();
|
||||
navigatorKey.currentState.openTransaction(
|
||||
(NavigatorTransaction transaction) => transaction.pop()
|
||||
);
|
||||
tester.pump(); // navigating always takes two frames
|
||||
tester.pump(new Duration(seconds: 1));
|
||||
|
||||
|
|
|
@ -22,14 +22,14 @@ class TestRoute extends Route<String> {
|
|||
results.add('$name: $s');
|
||||
}
|
||||
|
||||
void install(OverlayState overlay, OverlayEntry insertionPoint) {
|
||||
void install(OverlayEntry insertionPoint) {
|
||||
log('install');
|
||||
OverlayEntry entry = new OverlayEntry(
|
||||
builder: (BuildContext context) => new Container(),
|
||||
opaque: true
|
||||
);
|
||||
_entries.add(entry);
|
||||
overlay?.insert(entry, above: insertionPoint);
|
||||
navigator.overlay?.insert(entry, above: insertionPoint);
|
||||
routes.add(this);
|
||||
}
|
||||
|
||||
|
@ -73,11 +73,11 @@ class TestRoute extends Route<String> {
|
|||
void runNavigatorTest(
|
||||
WidgetTester tester,
|
||||
NavigatorState host,
|
||||
void test(NavigatorState transaction),
|
||||
NavigatorTransactionCallback test,
|
||||
List<String> expectations
|
||||
) {
|
||||
expect(host, isNotNull);
|
||||
test(host);
|
||||
host.openTransaction(test);
|
||||
expect(results, equals(expectations));
|
||||
results.clear();
|
||||
tester.pump();
|
||||
|
@ -95,7 +95,7 @@ void main() {
|
|||
runNavigatorTest(
|
||||
tester,
|
||||
host,
|
||||
(NavigatorState transaction) {
|
||||
(NavigatorTransaction transaction) {
|
||||
},
|
||||
[
|
||||
'initial: install',
|
||||
|
@ -106,7 +106,7 @@ void main() {
|
|||
runNavigatorTest(
|
||||
tester,
|
||||
host,
|
||||
(NavigatorState transaction) {
|
||||
(NavigatorTransaction transaction) {
|
||||
transaction.push(second = new TestRoute('second'));
|
||||
},
|
||||
[
|
||||
|
@ -118,7 +118,7 @@ void main() {
|
|||
runNavigatorTest(
|
||||
tester,
|
||||
host,
|
||||
(NavigatorState transaction) {
|
||||
(NavigatorTransaction transaction) {
|
||||
transaction.push(new TestRoute('third'));
|
||||
},
|
||||
[
|
||||
|
@ -130,7 +130,7 @@ void main() {
|
|||
runNavigatorTest(
|
||||
tester,
|
||||
host,
|
||||
(NavigatorState transaction) {
|
||||
(NavigatorTransaction transaction) {
|
||||
transaction.replace(oldRoute: second, newRoute: new TestRoute('two'));
|
||||
},
|
||||
[
|
||||
|
@ -143,7 +143,7 @@ void main() {
|
|||
runNavigatorTest(
|
||||
tester,
|
||||
host,
|
||||
(NavigatorState transaction) {
|
||||
(NavigatorTransaction transaction) {
|
||||
transaction.pop('hello');
|
||||
},
|
||||
[
|
||||
|
@ -155,7 +155,7 @@ void main() {
|
|||
runNavigatorTest(
|
||||
tester,
|
||||
host,
|
||||
(NavigatorState transaction) {
|
||||
(NavigatorTransaction transaction) {
|
||||
transaction.pop('good bye');
|
||||
},
|
||||
[
|
||||
|
@ -182,7 +182,7 @@ void main() {
|
|||
runNavigatorTest(
|
||||
tester,
|
||||
host,
|
||||
(NavigatorState transaction) {
|
||||
(NavigatorTransaction transaction) {
|
||||
},
|
||||
[
|
||||
'first: install',
|
||||
|
@ -193,7 +193,7 @@ void main() {
|
|||
runNavigatorTest(
|
||||
tester,
|
||||
host,
|
||||
(NavigatorState transaction) {
|
||||
(NavigatorTransaction transaction) {
|
||||
transaction.push(second = new TestRoute('second'));
|
||||
},
|
||||
[
|
||||
|
@ -205,7 +205,7 @@ void main() {
|
|||
runNavigatorTest(
|
||||
tester,
|
||||
host,
|
||||
(NavigatorState transaction) {
|
||||
(NavigatorTransaction transaction) {
|
||||
transaction.push(new TestRoute('third'));
|
||||
},
|
||||
[
|
||||
|
@ -217,7 +217,7 @@ void main() {
|
|||
runNavigatorTest(
|
||||
tester,
|
||||
host,
|
||||
(NavigatorState transaction) {
|
||||
(NavigatorTransaction transaction) {
|
||||
transaction.removeRouteBefore(second);
|
||||
},
|
||||
[
|
||||
|
@ -227,7 +227,7 @@ void main() {
|
|||
runNavigatorTest(
|
||||
tester,
|
||||
host,
|
||||
(NavigatorState transaction) {
|
||||
(NavigatorTransaction transaction) {
|
||||
transaction.pop('good bye');
|
||||
},
|
||||
[
|
||||
|
@ -239,7 +239,7 @@ void main() {
|
|||
runNavigatorTest(
|
||||
tester,
|
||||
host,
|
||||
(NavigatorState transaction) {
|
||||
(NavigatorTransaction transaction) {
|
||||
transaction.push(new TestRoute('three'));
|
||||
},
|
||||
[
|
||||
|
@ -252,7 +252,7 @@ void main() {
|
|||
runNavigatorTest(
|
||||
tester,
|
||||
host,
|
||||
(NavigatorState transaction) {
|
||||
(NavigatorTransaction transaction) {
|
||||
transaction.push(four = new TestRoute('four'));
|
||||
},
|
||||
[
|
||||
|
@ -264,7 +264,7 @@ void main() {
|
|||
runNavigatorTest(
|
||||
tester,
|
||||
host,
|
||||
(NavigatorState transaction) {
|
||||
(NavigatorTransaction transaction) {
|
||||
transaction.removeRouteBefore(four);
|
||||
},
|
||||
[
|
||||
|
@ -274,7 +274,7 @@ void main() {
|
|||
runNavigatorTest(
|
||||
tester,
|
||||
host,
|
||||
(NavigatorState transaction) {
|
||||
(NavigatorTransaction transaction) {
|
||||
transaction.pop('the end');
|
||||
},
|
||||
[
|
||||
|
@ -301,7 +301,7 @@ void main() {
|
|||
runNavigatorTest(
|
||||
tester,
|
||||
host,
|
||||
(NavigatorState transaction) {
|
||||
(NavigatorTransaction transaction) {
|
||||
},
|
||||
[
|
||||
'A: install',
|
||||
|
@ -311,7 +311,7 @@ void main() {
|
|||
runNavigatorTest(
|
||||
tester,
|
||||
host,
|
||||
(NavigatorState transaction) {
|
||||
(NavigatorTransaction transaction) {
|
||||
transaction.push(new TestRoute('B'));
|
||||
},
|
||||
[
|
||||
|
@ -324,7 +324,7 @@ void main() {
|
|||
runNavigatorTest(
|
||||
tester,
|
||||
host,
|
||||
(NavigatorState transaction) {
|
||||
(NavigatorTransaction transaction) {
|
||||
transaction.push(routeC = new TestRoute('C'));
|
||||
},
|
||||
[
|
||||
|
@ -337,7 +337,7 @@ void main() {
|
|||
runNavigatorTest(
|
||||
tester,
|
||||
host,
|
||||
(NavigatorState transaction) {
|
||||
(NavigatorTransaction transaction) {
|
||||
transaction.replaceRouteBefore(anchorRoute: routeC, newRoute: routeB = new TestRoute('b'));
|
||||
},
|
||||
[
|
||||
|
@ -350,7 +350,7 @@ void main() {
|
|||
runNavigatorTest(
|
||||
tester,
|
||||
host,
|
||||
(NavigatorState transaction) {
|
||||
(NavigatorTransaction transaction) {
|
||||
transaction.popUntil(routeB);
|
||||
},
|
||||
[
|
||||
|
|
Loading…
Reference in a new issue