提交 95e1e570 编写于 作者: A Adam Barth

Add Navigator.of

Now you don't need to pass the navigator around everywhere.
上级 69347130
......@@ -34,10 +34,6 @@ class Field extends StatelessComponent {
}
class AddressBookHome extends StatelessComponent {
AddressBookHome({ this.navigator });
final NavigatorState navigator;
Widget buildToolBar(BuildContext context) {
return new ToolBar(
left: new IconButton(icon: "navigation/arrow_back"),
......@@ -96,7 +92,7 @@ void main() {
title: 'Address Book',
theme: theme,
routes: <String, RouteBuilder>{
'/': (RouteArguments args) => new AddressBookHome(navigator: args.navigator)
'/': (RouteArguments args) => new AddressBookHome()
}
));
}
......@@ -67,7 +67,7 @@ class FeedFragmentState extends State<FeedFragment> {
void _showDrawer() {
showDrawer(
navigator: config.navigator,
context: context,
child: new Block([
new DrawerHeader(child: new Text('Fitness')),
new DrawerItem(
......@@ -117,7 +117,7 @@ class FeedFragmentState extends State<FeedFragment> {
void _handleItemDismissed(FitnessItem item) {
config.onItemDeleted(item);
showSnackBar(
navigator: config.navigator,
context: context,
placeholderKey: _snackBarPlaceholderKey,
content: new Text("Item deleted."),
actions: [new SnackBarAction(label: "UNDO", onPressed: () {
......@@ -191,7 +191,7 @@ class FeedFragmentState extends State<FeedFragment> {
}
void _handleActionButtonPressed() {
showDialog(config.navigator, (NavigatorState navigator) => new AddItemDialog(navigator)).then((routeName) {
showDialog(context: context, child: new AddItemDialog()).then((routeName) {
if (routeName != null)
config.navigator.pushNamed(routeName);
});
......@@ -220,10 +220,6 @@ class FeedFragmentState extends State<FeedFragment> {
}
class AddItemDialog extends StatefulComponent {
AddItemDialog(this.navigator);
final NavigatorState navigator;
AddItemDialogState createState() => new AddItemDialogState();
}
......@@ -253,16 +249,20 @@ class AddItemDialogState extends State<AddItemDialog> {
return new Dialog(
title: new Text("What are you doing?"),
content: new Block(menuItems),
onDismiss: config.navigator.pop,
onDismiss: () {
Navigator.of(context).pop();
},
actions: [
new FlatButton(
child: new Text('CANCEL'),
onPressed: config.navigator.pop
onPressed: () {
Navigator.of(context).pop();
}
),
new FlatButton(
child: new Text('ADD'),
onPressed: () {
config.navigator.pop(_addItemRoute);
Navigator.of(context).pop(_addItemRoute);
}
),
]
......
......@@ -55,9 +55,8 @@ class MeasurementRow extends FitnessItemRow {
}
class MeasurementDateDialog extends StatefulComponent {
MeasurementDateDialog({ this.navigator, this.previousDate });
MeasurementDateDialog({ this.previousDate });
final NavigatorState navigator;
final DateTime previousDate;
MeasurementDateDialogState createState() => new MeasurementDateDialogState();
......@@ -89,12 +88,14 @@ class MeasurementDateDialogState extends State<MeasurementDateDialog> {
actions: [
new FlatButton(
child: new Text('CANCEL'),
onPressed: config.navigator.pop
onPressed: () {
Navigator.of(context).pop();
}
),
new FlatButton(
child: new Text('OK'),
onPressed: () {
config.navigator.pop(_selectedDate);
Navigator.of(context).pop(_selectedDate);
}
),
]
......@@ -124,7 +125,7 @@ class MeasurementFragmentState extends State<MeasurementFragment> {
} on FormatException catch(e) {
print("Exception $e");
showSnackBar(
navigator: config.navigator,
context: context,
placeholderKey: _snackBarPlaceholderKey,
content: new Text('Save failed')
);
......@@ -157,16 +158,16 @@ class MeasurementFragmentState extends State<MeasurementFragment> {
static final GlobalKey weightKey = new GlobalKey();
void _handleDatePressed() {
showDialog(config.navigator, (NavigatorState navigator) {
return new MeasurementDateDialog(navigator: navigator, previousDate: _when);
}).then((DateTime value) {
if (value == null)
return;
Future _handleDatePressed() async {
DateTime value = await showDialog(
context: context,
child: new MeasurementDateDialog(previousDate: _when)
);
if (value != null) {
setState(() {
_when = value;
});
});
}
}
Widget buildBody(BuildContext context) {
......
......@@ -60,9 +60,10 @@ class SettingsFragmentState extends State<SettingsFragment> {
}
}
void _handleGoalWeightPressed() {
showDialog(config.navigator, (NavigatorState navigator) {
return new Dialog(
Future _handleGoalWeightPressed() async {
double goalWeight = await showDialog(
context: context,
child: new Dialog(
title: new Text("Goal Weight"),
content: new Input(
key: weightGoalKey,
......@@ -71,24 +72,25 @@ class SettingsFragmentState extends State<SettingsFragment> {
onChanged: _handleGoalWeightChanged
),
onDismiss: () {
navigator.pop();
Navigator.of(context).pop();
},
actions: [
new FlatButton(
child: new Text('CANCEL'),
onPressed: () {
navigator.pop();
Navigator.of(context).pop();
}
),
new FlatButton(
child: new Text('SAVE'),
onPressed: () {
navigator.pop(_goalWeight);
Navigator.of(context).pop(_goalWeight);
}
),
]
);
}).then((double goalWeight) => config.updater(goalWeight: goalWeight));
)
);
config.updater(goalWeight: goalWeight);
}
Widget buildSettingsPane(BuildContext context) {
......
......@@ -81,7 +81,7 @@ class StocksAppState extends State<StocksApp> {
if (path.length != 3)
return null;
if (_stocks.containsKey(path[2]))
return (RouteArguments args) => new StockSymbolViewer(args.navigator, _stocks[path[2]]);
return (RouteArguments args) => new StockSymbolViewer(_stocks[path[2]]);
return null;
}
return null;
......
......@@ -67,7 +67,8 @@ class StockHomeState extends State<StockHome> {
}
void _handleMenuShow() {
showStockMenu(config.navigator,
showStockMenu(
context: context,
autorefresh: _autorefresh,
onAutorefreshChanged: _handleAutorefreshChanged
);
......@@ -75,7 +76,7 @@ class StockHomeState extends State<StockHome> {
void _showDrawer() {
showDrawer(
navigator: config.navigator,
context: context,
child: new Block(<Widget>[
new DrawerHeader(child: new Text('Stocks')),
new DrawerItem(
......@@ -86,8 +87,9 @@ class StockHomeState extends State<StockHome> {
new DrawerItem(
icon: 'action/account_balance',
onPressed: () {
showDialog(config.navigator, (NavigatorState navigator) {
return new Dialog(
showDialog(
context: context,
child: new Dialog(
title: new Text('Not Implemented'),
content: new Text('This feature has not yet been implemented.'),
actions: <Widget>[
......@@ -95,18 +97,18 @@ class StockHomeState extends State<StockHome> {
child: new Text('USE IT'),
enabled: false,
onPressed: () {
navigator.pop(false);
config.navigator.pop(false);
}
),
new FlatButton(
child: new Text('OH WELL'),
onPressed: () {
navigator.pop(false);
config.navigator.pop(false);
}
),
]
);
});
)
);
},
child: new Text('Account Balance')
),
......@@ -246,7 +248,7 @@ class StockHomeState extends State<StockHome> {
void _handleStockPurchased() {
showSnackBar(
navigator: config.navigator,
context: context,
placeholderKey: _snackBarPlaceholderKey,
content: new Text("Stock purchased!"),
actions: <SnackBarAction>[
......
......@@ -8,44 +8,42 @@ enum _MenuItems { autorefresh, autorefreshCheckbox, add, remove }
const double _kMenuMargin = 16.0; // 24.0 on tablet
Future showStockMenu(NavigatorState navigator, { bool autorefresh, ValueChanged onAutorefreshChanged }) async {
Future showStockMenu({BuildContext context, bool autorefresh, ValueChanged onAutorefreshChanged }) async {
switch (await showMenu(
navigator: navigator,
context: context,
position: new MenuPosition(
right: ui.view.paddingRight + _kMenuMargin,
top: ui.view.paddingTop + _kMenuMargin
),
builder: (NavigatorState navigator) {
return <PopupMenuItem>[
new PopupMenuItem(
value: _MenuItems.autorefresh,
child: new Row(<Widget>[
new Flexible(child: new Text('Autorefresh')),
new Checkbox(
value: autorefresh,
onChanged: (bool value) {
navigator.setState(() {
autorefresh = value;
});
navigator.pop(_MenuItems.autorefreshCheckbox);
}
)
]
)
),
new PopupMenuItem(
value: _MenuItems.add,
child: new Text('Add stock')
),
new PopupMenuItem(
value: _MenuItems.remove,
child: new Text('Remove stock')
),
];
}
items: <PopupMenuItem>[
new PopupMenuItem(
value: _MenuItems.autorefresh,
child: new Row(<Widget>[
new Flexible(child: new Text('Autorefresh')),
new Checkbox(
value: autorefresh,
onChanged: (bool value) {
Navigator.of(context).setState(() {
autorefresh = value;
});
Navigator.of(context).pop(_MenuItems.autorefreshCheckbox);
}
)
]
)
),
new PopupMenuItem(
value: _MenuItems.add,
child: new Text('Add stock')
),
new PopupMenuItem(
value: _MenuItems.remove,
child: new Text('Remove stock')
),
]
)) {
case _MenuItems.autorefresh:
navigator.setState(() {
Navigator.of(context).setState(() {
autorefresh = !autorefresh;
});
continue autorefreshNotify;
......@@ -55,8 +53,9 @@ Future showStockMenu(NavigatorState navigator, { bool autorefresh, ValueChanged
break;
case _MenuItems.add:
case _MenuItems.remove:
await showDialog(navigator, (NavigatorState navigator) {
return new Dialog(
await showDialog(
context: context,
child: new Dialog(
title: new Text('Not Implemented'),
content: new Text('This feature has not yet been implemented.'),
actions: <Widget>[
......@@ -76,14 +75,14 @@ Future showStockMenu(NavigatorState navigator, { bool autorefresh, ValueChanged
new FlatButton(
child: new Text('OH WELL'),
onPressed: () {
navigator.pop(false);
Navigator.of(context).pop(false);
}
),
]
);
});
)
);
break;
default:
// menu was canceled.
}
}
\ No newline at end of file
}
......@@ -35,29 +35,30 @@ class StockSettingsState extends State<StockSettings> {
_handleOptimismChanged(false);
break;
case StockMode.pessimistic:
showDialog(config.navigator, (NavigatorState navigator) {
return new Dialog(
showDialog(
context: context,
child: new Dialog(
title: new Text("Change mode?"),
content: new Text("Optimistic mode means everything is awesome. Are you sure you can handle that?"),
onDismiss: () {
navigator.pop(false);
config.navigator.pop(false);
},
actions: <Widget>[
new FlatButton(
child: new Text('NO THANKS'),
onPressed: () {
navigator.pop(false);
config.navigator.pop(false);
}
),
new FlatButton(
child: new Text('AGREE'),
onPressed: () {
navigator.pop(true);
config.navigator.pop(true);
}
),
]
);
}).then(_handleOptimismChanged);
)
).then(_handleOptimismChanged);
break;
}
}
......
......@@ -5,9 +5,8 @@
part of stocks;
class StockSymbolViewer extends StatelessComponent {
StockSymbolViewer(this.navigator, this.stock);
StockSymbolViewer(this.stock);
final NavigatorState navigator;
final Stock stock;
Widget build(BuildContext context) {
......@@ -20,7 +19,9 @@ class StockSymbolViewer extends StatelessComponent {
toolBar: new ToolBar(
left: new IconButton(
icon: 'navigation/arrow_back',
onPressed: navigator.pop
onPressed: () {
Navigator.of(context).pop();
}
),
center: new Text(stock.name)
),
......
......@@ -19,10 +19,6 @@ class CardModel {
}
class CardCollection extends StatefulComponent {
CardCollection({ this.navigator });
final NavigatorState navigator;
CardCollectionState createState() => new CardCollectionState();
}
......@@ -113,7 +109,7 @@ class CardCollectionState extends State<CardCollection> {
void _showDrawer() {
showDrawer(
navigator: config.navigator,
context: context,
child: new IconTheme(
data: const IconThemeData(color: IconThemeColor.black),
child: new Block([
......@@ -169,7 +165,7 @@ class CardCollectionState extends State<CardCollection> {
setState(() {
_dismissDirection = newDismissDirection;
});
config.navigator.pop();
Navigator.of(context).pop();
}
Widget buildDrawerCheckbox(String label, bool value, Function callback) {
......@@ -374,7 +370,7 @@ void main() {
runApp(new MaterialApp(
title: 'Cards',
routes: {
'/': (RouteArguments args) => new CardCollection(navigator: args.navigator),
'/': (RouteArguments args) => new CardCollection(),
}
));
}
......@@ -6,10 +6,6 @@ import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class IndexedStackDemo extends StatefulComponent {
IndexedStackDemo({ this.navigator });
final NavigatorState navigator;
IndexedStackDemoState createState() => new IndexedStackDemoState();
}
......@@ -23,7 +19,7 @@ class IndexedStackDemoState extends State<IndexedStackDemo> {
});
}
List <PopupMenuItem> _buildMenu(NavigatorState navigator) {
List <PopupMenuItem> _buildMenu() {
TextStyle style = const TextStyle(fontSize: 18.0, fontWeight: bold);
String pad = '';
return new List.generate(_itemCount, (int i) {
......@@ -33,7 +29,7 @@ class IndexedStackDemoState extends State<IndexedStackDemo> {
}
Widget build(BuildContext context) {
List <PopupMenuItem> items = _buildMenu(config.navigator);
List <PopupMenuItem> items = _buildMenu();
IndexedStack indexedStack = new IndexedStack(items, index: _itemIndex, horizontalAlignment: 0.5);
return new Scaffold(
......@@ -61,7 +57,7 @@ void main() {
accentColor: Colors.redAccent[200]
),
routes: {
'/': (RouteArguments args) => new IndexedStackDemo(navigator: args.navigator),
'/': (RouteArguments args) => new IndexedStackDemo(),
}
));
}
......@@ -15,10 +15,6 @@ class CardModel {
}
class PageableListApp extends StatefulComponent {
PageableListApp({ this.navigator });
final NavigatorState navigator;
PageableListAppState createState() => new PageableListAppState();
}
......@@ -89,7 +85,7 @@ class PageableListAppState extends State<PageableListApp> {
void _showDrawer() {
showDrawer(
navigator: config.navigator,
context: context,
child: new Block([
new DrawerHeader(child: new Text('Options')),
new DrawerItem(
......@@ -161,7 +157,7 @@ void main() {
accentColor: Colors.redAccent[200]
),
routes: {
'/': (RouteArguments args) => new PageableListApp(navigator: args.navigator),
'/': (RouteArguments args) => new PageableListApp(),
}
));
}
......@@ -6,10 +6,6 @@ import 'package:intl/intl.dart';
import 'package:flutter/material.dart';
class ScrollbarApp extends StatefulComponent {
ScrollbarApp({ this.navigator });
final NavigatorState navigator;
ScrollbarAppState createState() => new ScrollbarAppState();
}
......@@ -65,7 +61,7 @@ void main() {
accentColor: Colors.redAccent[200]
),
routes: {
'/': (RouteArguments args) => new ScrollbarApp(navigator: args.navigator),
'/': (RouteArguments args) => new ScrollbarApp(),
}
));
}
......@@ -153,15 +153,15 @@ class _DialogRoute extends PerformanceRoute {
}
}
Future showDialog(NavigatorState navigator, DialogBuilder builder) {
Future showDialog({ BuildContext context, Widget child }) {
Completer completer = new Completer();
navigator.push(new _DialogRoute(
Navigator.of(context).push(new _DialogRoute(
completer: completer,
builder: (RouteArguments args) {
return new Focus(
key: new GlobalObjectKey(completer),
autofocus: true,
child: builder(args.navigator)
child: child
);
}
));
......
......@@ -169,7 +169,6 @@ class _DrawerRoute extends Route {
}
}
void showDrawer({ NavigatorState navigator, Widget child, int level: 3 }) {
assert(navigator != null);
navigator.push(new _DrawerRoute(child: child, level: level));
void showDrawer({ BuildContext context, Widget child, int level: 3 }) {
Navigator.of(context).push(new _DrawerRoute(child: child, level: level));
}
......@@ -22,14 +22,11 @@ const double _kMenuMaxWidth = 5.0 * _kMenuWidthStep;
const double _kMenuHorizontalPadding = 16.0;
const double _kMenuVerticalPadding = 8.0;
typedef List<PopupMenuItem> PopupMenuItemsBuilder(NavigatorState navigator);
class PopupMenu extends StatelessComponent {
PopupMenu({
Key key,
this.items,
this.level: 4,
this.navigator,
this.performance
}) : super(key: key) {
assert(items != null);
......@@ -38,7 +35,6 @@ class PopupMenu extends StatelessComponent {
final List<PopupMenuItem> items;
final int level;
final NavigatorState navigator;
final PerformanceView performance;
Widget build(BuildContext context) {
......@@ -58,7 +54,7 @@ class PopupMenu extends StatelessComponent {
performance: performance,
opacity: new AnimatedValue<double>(0.0, end: 1.0, curve: new Interval(start, end)),
child: new InkWell(
onTap: () { navigator.pop(items[i].value); },
onTap: () { Navigator.of(context).pop(items[i].value); },
child: items[i]
))
);
......@@ -114,11 +110,11 @@ class MenuPosition {
}
class _MenuRoute extends PerformanceRoute {
_MenuRoute({ this.completer, this.position, this.builder, this.level });
_MenuRoute({ this.completer, this.position, this.items, this.level });
final Completer completer;
final MenuPosition position;
final PopupMenuItemsBuilder builder;
final List<PopupMenuItem> items;
final int level;
Performance createPerformance() {
......@@ -144,9 +140,8 @@ class _MenuRoute extends PerformanceRoute {
key: new GlobalObjectKey(this),
autofocus: true,
child: new PopupMenu(
items: builder != null ? builder(navigator) : const <PopupMenuItem>[],
items: items,
level: level,
navigator: navigator,
performance: performance
)
)
......@@ -159,12 +154,12 @@ class _MenuRoute extends PerformanceRoute {
}
}
Future showMenu({ NavigatorState navigator, MenuPosition position, PopupMenuItemsBuilder builder, int level: 4 }) {
Future showMenu({ BuildContext context, MenuPosition position, List<PopupMenuItem> items, int level: 4 }) {
Completer completer = new Completer();
navigator.push(new _MenuRoute(
Navigator.of(context).push(new _MenuRoute(
completer: completer,
position: position,
builder: builder,
items: items,
level: level
));
return completer.future;
......
......@@ -105,7 +105,7 @@ class _SnackBarRoute extends PerformanceRoute {
Widget build(RouteArguments args) => null;
}
void showSnackBar({ NavigatorState navigator, GlobalKey<PlaceholderState> placeholderKey, Widget content, List<SnackBarAction> actions }) {
void showSnackBar({ BuildContext context, GlobalKey<PlaceholderState> placeholderKey, Widget content, List<SnackBarAction> actions }) {
Route route = new _SnackBarRoute();
SnackBar snackBar = new SnackBar(
content: content,
......@@ -113,5 +113,5 @@ void showSnackBar({ NavigatorState navigator, GlobalKey<PlaceholderState> placeh
performance: route.performance
);
placeholderKey.currentState.child = snackBar;
navigator.push(route);
Navigator.of(context).push(route);
}
......@@ -7,7 +7,6 @@ import 'package:flutter/rendering.dart';
import 'basic.dart';
import 'framework.dart';
import 'navigator.dart';
import 'transitions.dart';
// Heroes are the parts of an application's screen-to-screen transitions where a
......@@ -51,7 +50,7 @@ import 'transitions.dart';
// TODO(ianh): If the widgets use Inherited properties, they are taken from the
// Navigator's position in the widget hierarchy, not the source or target. We
// should interpolate the inherited properties from their value at the source to
// their value at the target. See: https://github.com/flutter/engine/issues/1698
// their value at the target. See: https://github.com/flutter/engine/issues/1698
final Object centerOfAttentionHeroTag = new Object();
......@@ -77,7 +76,6 @@ abstract class HeroHandle {
class Hero extends StatefulComponent {
Hero({
Key key,
this.navigator,
this.tag,
this.child,
this.turns: 1
......@@ -85,7 +83,6 @@ class Hero extends StatefulComponent {
assert(tag != null);
}
final NavigatorState navigator;
final Object tag;
final Widget child;
final int turns;
......@@ -205,7 +202,7 @@ class HeroState extends State<Hero> implements HeroHandle {
child: config.child
)
);
case _HeroMode.taken:
case _HeroMode.taken:
return new SizedBox(width: _size.width, height: _size.height);
}
}
......
......@@ -47,6 +47,22 @@ class Navigator extends StatefulComponent {
final RouteGenerator onGenerateRoute;
final RouteBuilder onUnknownRoute;
static NavigatorState of(BuildContext context) {
NavigatorState result;
bool visitor(Element element) {
if (element is StatefulComponentElement) {
if (element.state is NavigatorState) {
result = element.state;
return false;
}
}
return true;
}
if (visitor(context))
context.visitAncestorElements(visitor);
return result;
}
NavigatorState createState() => new NavigatorState();
}
......@@ -54,7 +70,7 @@ class Navigator extends StatefulComponent {
// It also animates between these pages.
// Pages can have "heroes", which are UI elements that animate from point to point.
// These animations are called journeys.
//
//
// Journeys can start in two conditions:
// - Everything is calm, and we have no heroes in flight. In this case, we will
// have to collect the heroes from the route we're starting at and the route
......
......@@ -21,7 +21,7 @@ void main() {
);
tester.pump(); // no effect
expect(tester.findText('drawer'), isNull);
showDrawer(navigator: navigator, child: new Text('drawer'));
showDrawer(context: navigator.context, child: new Text('drawer'));
tester.pump(); // drawer should be starting to animate in
expect(tester.findText('drawer'), isNotNull);
tester.pump(new Duration(seconds: 1)); // animation done
......@@ -50,7 +50,7 @@ void main() {
);
tester.pump(); // no effect
expect(tester.findText('drawer'), isNull);
showDrawer(navigator: navigator, child: new Text('drawer'));
showDrawer(context: navigator.context, child: new Text('drawer'));
tester.pump(); // drawer should be starting to animate in
expect(tester.findText('drawer'), isNotNull);
tester.pump(new Duration(seconds: 1)); // animation done
......
......@@ -16,7 +16,7 @@ void main() {
return new GestureDetector(
onTap: () {
showSnackBar(
navigator: args.navigator,
context: args.navigator.context,
placeholderKey: placeholderKey,
content: new Text(helloSnackBar)
);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册