Commit ab74b178 authored by Ian Hickson's avatar Ian Hickson

Merge pull request #705 from Hixie/yak3-material-app-route-classes

Let MaterialApp.onGenerateRoute return a Route
parents 2ef0b569 df07a69b
...@@ -8,7 +8,6 @@ import 'dart:async'; ...@@ -8,7 +8,6 @@ import 'dart:async';
import 'dart:math' as math; import 'dart:math' as math;
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:flutter/animation.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
...@@ -75,16 +74,19 @@ class StocksAppState extends State<StocksApp> { ...@@ -75,16 +74,19 @@ class StocksAppState extends State<StocksApp> {
} }
} }
RouteBuilder _getRoute(String name) { Route _getRoute(NamedRouteSettings settings) {
List<String> path = name.split('/'); List<String> path = settings.name.split('/');
if (path[0] != '') if (path[0] != '')
return null; return null;
if (path[1] == 'stock') { if (path[1] == 'stock') {
if (path.length != 3) if (path.length != 3)
return null; return null;
if (_stocks.containsKey(path[2])) if (_stocks.containsKey(path[2])) {
return (RouteArguments args) => new StockSymbolPage(stock: _stocks[path[2]]); return new MaterialPageRoute(
return null; settings: settings,
builder: (BuildContext context) => new StockSymbolPage(stock: _stocks[path[2]])
);
}
} }
return null; return null;
} }
......
...@@ -145,22 +145,13 @@ class StockHomeState extends State<StockHome> { ...@@ -145,22 +145,13 @@ class StockHomeState extends State<StockHome> {
} }
Widget buildToolBar() { Widget buildToolBar() {
PageRoute page = ModalRoute.of(context);
return new ToolBar( return new ToolBar(
elevation: 0, elevation: 0,
left: new IconButton( left: new IconButton(
icon: "navigation/menu", icon: "navigation/menu",
onPressed: () => _scaffoldKey.currentState?.openDrawer() onPressed: () => _scaffoldKey.currentState?.openDrawer()
), ),
center: new FadeTransition( center: new Text('Stocks'),
opacity: new AnimatedValue<double>(
1.0,
end: 0.0,
curve: const Interval(0.0, 0.5)
),
performance: page.forwardPerformance,
child: new Text('Stocks')
),
right: <Widget>[ right: <Widget>[
new IconButton( new IconButton(
icon: "action/search", icon: "action/search",
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
part of stocks; part of stocks;
class StockSymbolView extends StatelessComponent { class StockSymbolView extends StatelessComponent {
StockSymbolView({ this.stock}); StockSymbolView({ this.stock });
final Stock stock; final Stock stock;
...@@ -20,28 +20,28 @@ class StockSymbolView extends StatelessComponent { ...@@ -20,28 +20,28 @@ class StockSymbolView extends StatelessComponent {
padding: new EdgeDims.all(20.0), padding: new EdgeDims.all(20.0),
child: new Column(<Widget>[ child: new Column(<Widget>[
new Row(<Widget>[ new Row(<Widget>[
new Text( new Text(
'${stock.symbol}', '${stock.symbol}',
style: Theme.of(context).text.display2 style: Theme.of(context).text.display2
), ),
new Hero( new Hero(
key: new ObjectKey(stock), key: new ObjectKey(stock),
tag: StockRowPartKind.arrow, tag: StockRowPartKind.arrow,
turns: 2, turns: 2,
child: new StockArrow(percentChange: stock.percentChange) child: new StockArrow(percentChange: stock.percentChange)
), ),
], ],
justifyContent: FlexJustifyContent.spaceBetween justifyContent: FlexJustifyContent.spaceBetween
), ),
new Text('Last Sale', style: headings), new Text('Last Sale', style: headings),
new Text('$lastSale ($changeInPrice)'), new Text('$lastSale ($changeInPrice)'),
new Container( new Container(
height: 8.0 height: 8.0
), ),
new Text('Market Cap', style: headings), new Text('Market Cap', style: headings),
new Text('${stock.marketCap}'), new Text('${stock.marketCap}'),
], ],
justifyContent: FlexJustifyContent.collapse justifyContent: FlexJustifyContent.collapse
) )
); );
} }
...@@ -53,7 +53,6 @@ class StockSymbolPage extends StatelessComponent { ...@@ -53,7 +53,6 @@ class StockSymbolPage extends StatelessComponent {
final Stock stock; final Stock stock;
Widget build(BuildContext context) { Widget build(BuildContext context) {
PageRoute page = ModalRoute.of(context);
return new Scaffold( return new Scaffold(
toolBar: new ToolBar( toolBar: new ToolBar(
left: new IconButton( left: new IconButton(
...@@ -62,15 +61,7 @@ class StockSymbolPage extends StatelessComponent { ...@@ -62,15 +61,7 @@ class StockSymbolPage extends StatelessComponent {
Navigator.pop(context); Navigator.pop(context);
} }
), ),
center: new FadeTransition( center: new Text(stock.name)
opacity: new AnimatedValue<double>(
0.0,
end: 1.0,
curve: const Interval(0.5, 1.0)
),
performance: page.performance,
child: new Text(stock.name)
)
), ),
body: new Block(<Widget>[ body: new Block(<Widget>[
new Container( new Container(
......
...@@ -37,7 +37,6 @@ class RouteArguments { ...@@ -37,7 +37,6 @@ class RouteArguments {
final BuildContext context; final BuildContext context;
} }
typedef Widget RouteBuilder(RouteArguments args); typedef Widget RouteBuilder(RouteArguments args);
typedef RouteBuilder RouteGenerator(String name);
class MaterialApp extends StatefulComponent { class MaterialApp extends StatefulComponent {
MaterialApp({ MaterialApp({
...@@ -54,7 +53,7 @@ class MaterialApp extends StatefulComponent { ...@@ -54,7 +53,7 @@ class MaterialApp extends StatefulComponent {
final String title; final String title;
final ThemeData theme; final ThemeData theme;
final Map<String, RouteBuilder> routes; final Map<String, RouteBuilder> routes;
final RouteGenerator onGenerateRoute; final RouteFactory onGenerateRoute;
_MaterialAppState createState() => new _MaterialAppState(); _MaterialAppState createState() => new _MaterialAppState();
} }
...@@ -93,13 +92,18 @@ class _MaterialAppState extends State<MaterialApp> implements BindingObserver { ...@@ -93,13 +92,18 @@ class _MaterialAppState extends State<MaterialApp> implements BindingObserver {
final HeroController _heroController = new HeroController(); final HeroController _heroController = new HeroController();
Route _generateRoute(NamedRouteSettings settings) { Route _generateRoute(NamedRouteSettings settings) {
return new MaterialPageRoute( RouteBuilder builder = config.routes[settings.name];
builder: (BuildContext context) { if (builder != null) {
RouteBuilder builder = config.routes[settings.name] ?? config.onGenerateRoute(settings.name); return new MaterialPageRoute(
return builder(new RouteArguments(context: context)); builder: (BuildContext context) {
}, return builder(new RouteArguments(context: context));
settings: settings },
); settings: settings
);
}
if (config.onGenerateRoute != null)
return config.onGenerateRoute(settings);
return null;
} }
Widget build(BuildContext context) { Widget build(BuildContext context) {
......
...@@ -52,7 +52,6 @@ class MaterialPageRoute<T> extends PageRoute<T> { ...@@ -52,7 +52,6 @@ class MaterialPageRoute<T> extends PageRoute<T> {
final WidgetBuilder builder; final WidgetBuilder builder;
Duration get transitionDuration => kMaterialPageRouteTransitionDuration; Duration get transitionDuration => kMaterialPageRouteTransitionDuration;
bool get barrierDismissable => false;
Color get barrierColor => Colors.black54; Color get barrierColor => Colors.black54;
Widget buildPage(BuildContext context) { Widget buildPage(BuildContext context) {
......
...@@ -197,7 +197,13 @@ class NavigatorState extends State<Navigator> { ...@@ -197,7 +197,13 @@ class NavigatorState extends State<Navigator> {
name: name, name: name,
mostValuableKeys: mostValuableKeys mostValuableKeys: mostValuableKeys
); );
_push(config.onGenerateRoute(settings) ?? config.onUnknownRoute(settings)); Route route = config.onGenerateRoute(settings);
if (route == null) {
assert(config.onUnknownRoute != null);
route = config.onUnknownRoute(settings);
assert(route != null);
}
_push(route);
} }
void _push(Route route, { Set<Key> mostValuableKeys }) { void _push(Route route, { Set<Key> mostValuableKeys }) {
......
...@@ -433,4 +433,5 @@ abstract class PageRoute<T> extends ModalRoute<T> { ...@@ -433,4 +433,5 @@ abstract class PageRoute<T> extends ModalRoute<T> {
NamedRouteSettings settings: const NamedRouteSettings() NamedRouteSettings settings: const NamedRouteSettings()
}) : super(completer: completer, settings: settings); }) : super(completer: completer, settings: settings);
bool get opaque => true; bool get opaque => true;
bool get barrierDismissable => false;
} }
...@@ -21,6 +21,7 @@ class WidgetTester { ...@@ -21,6 +21,7 @@ class WidgetTester {
clock = async.getClock(new DateTime.utc(2015, 1, 1)) { clock = async.getClock(new DateTime.utc(2015, 1, 1)) {
timeDilation = 1.0; timeDilation = 1.0;
ui.window.onBeginFrame = null; ui.window.onBeginFrame = null;
runApp(new ErrorWidget()); // flush out the last build entirely
} }
final FakeAsync async; final FakeAsync async;
......
...@@ -65,14 +65,14 @@ void main() { ...@@ -65,14 +65,14 @@ void main() {
bool showBottomSheetThenCalled = false; bool showBottomSheetThenCalled = false;
tester.pumpWidget(new MaterialApp( tester.pumpWidget(new MaterialApp(
routes: <String, RouteBuilder>{ routes: <String, RouteBuilder>{
'/': (RouteArguments args) { '/': (RouteArguments args) {
return new Scaffold( return new Scaffold(
key: scaffoldKey, key: scaffoldKey,
body: new Center(child: new Text('body')) body: new Center(child: new Text('body'))
); );
}
} }
}
)); ));
expect(showBottomSheetThenCalled, isFalse); expect(showBottomSheetThenCalled, isFalse);
......
...@@ -50,9 +50,7 @@ void pageRight(WidgetTester tester) { ...@@ -50,9 +50,7 @@ void pageRight(WidgetTester tester) {
} }
void main() { void main() {
// PageableList with itemsWrap: false test('PageableList with itemsWrap: false', () {
test('Scroll left from page 0 to page 1', () {
testWidgets((WidgetTester tester) { testWidgets((WidgetTester tester) {
currentPage = null; currentPage = null;
itemsWrap = false; itemsWrap = false;
...@@ -60,32 +58,14 @@ void main() { ...@@ -60,32 +58,14 @@ void main() {
expect(currentPage, isNull); expect(currentPage, isNull);
pageLeft(tester); pageLeft(tester);
expect(currentPage, equals(1)); expect(currentPage, equals(1));
});
});
test('Scroll right from page 1 to page 0', () {
testWidgets((WidgetTester tester) {
itemsWrap = false;
tester.pumpWidget(buildFrame());
expect(currentPage, equals(1));
pageRight(tester); pageRight(tester);
expect(currentPage, equals(0)); expect(currentPage, equals(0));
});
});
test('Scroll right from page 0 does nothing (underscroll)', () {
testWidgets((WidgetTester tester) {
itemsWrap = false;
tester.pumpWidget(buildFrame());
expect(currentPage, equals(0));
pageRight(tester); pageRight(tester);
expect(currentPage, equals(0)); expect(currentPage, equals(0));
}); });
}); });
// PageableList with itemsWrap: true test('PageableList with itemsWrap: true', () {
test('Scroll left page 0 to page 1, itemsWrap: true', () {
testWidgets((WidgetTester tester) { testWidgets((WidgetTester tester) {
tester.pumpWidget(new Container()); tester.pumpWidget(new Container());
currentPage = null; currentPage = null;
...@@ -94,22 +74,8 @@ void main() { ...@@ -94,22 +74,8 @@ void main() {
expect(currentPage, isNull); expect(currentPage, isNull);
pageLeft(tester); pageLeft(tester);
expect(currentPage, equals(1)); expect(currentPage, equals(1));
});
});
test('Scroll right from page 1 to page 0, itemsWrap: true', () {
testWidgets((WidgetTester tester) {
tester.pumpWidget(buildFrame());
expect(currentPage, equals(1));
pageRight(tester); pageRight(tester);
expect(currentPage, equals(0)); expect(currentPage, equals(0));
});
});
test('Scroll right from page 0 to page 5, itemsWrap: true (underscroll)', () {
testWidgets((WidgetTester tester) {
tester.pumpWidget(buildFrame());
expect(currentPage, equals(0));
pageRight(tester); pageRight(tester);
expect(currentPage, equals(5)); expect(currentPage, equals(5));
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment