Commit 706b272e authored by Adam Barth's avatar Adam Barth

Create the Performance for a Route earlier

Instead of waiting until build(), we now create the performance for a route in
its constructor.
parent 48142d68
No related merge requests found
...@@ -18,7 +18,7 @@ class RouteArguments { ...@@ -18,7 +18,7 @@ class RouteArguments {
typedef Widget RouteBuilder(RouteArguments args); typedef Widget RouteBuilder(RouteArguments args);
typedef RouteBuilder RouteGenerator(String name); typedef RouteBuilder RouteGenerator(String name);
typedef void StateRouteCallback(StateRoute route); typedef void StateRouteCallback(StateRoute route);
typedef void NotificationCallback(); typedef void _RouteCallback(Route route);
class Navigator extends StatefulComponent { class Navigator extends StatefulComponent {
Navigator({ Navigator({
...@@ -51,7 +51,7 @@ class NavigatorState extends State<Navigator> { ...@@ -51,7 +51,7 @@ class NavigatorState extends State<Navigator> {
PageRoute route = new PageRoute(config.routes['/']); PageRoute route = new PageRoute(config.routes['/']);
assert(route != null); assert(route != null);
assert(!route.ephemeral); assert(!route.ephemeral);
_history.add(route); _insertRoute(route);
} }
void pushState(State owner, Function callback) { void pushState(State owner, Function callback) {
...@@ -76,6 +76,13 @@ class NavigatorState extends State<Navigator> { ...@@ -76,6 +76,13 @@ class NavigatorState extends State<Navigator> {
push(new PageRoute(builder)); push(new PageRoute(builder));
} }
void _insertRoute(Route route) {
_history.insert(_currentPosition, route);
route._onDismissed = _handleRouteDismissed;
route._onRemoveRoute = _handleRemoveRoute;
route.didPush();
}
void push(Route route) { void push(Route route) {
assert(!_debugCurrentlyHaveRoute(route)); assert(!_debugCurrentlyHaveRoute(route));
setState(() { setState(() {
...@@ -84,8 +91,8 @@ class NavigatorState extends State<Navigator> { ...@@ -84,8 +91,8 @@ class NavigatorState extends State<Navigator> {
currentRoute.didPop(null); currentRoute.didPop(null);
_currentPosition -= 1; _currentPosition -= 1;
} }
_history.insert(_currentPosition + 1, route);
_currentPosition += 1; _currentPosition += 1;
_insertRoute(route);
}); });
} }
...@@ -122,6 +129,19 @@ class NavigatorState extends State<Navigator> { ...@@ -122,6 +129,19 @@ class NavigatorState extends State<Navigator> {
return index >= 0 && index <= _currentPosition; return index >= 0 && index <= _currentPosition;
} }
void _handleRouteDismissed(Route route) {
assert(_history.contains(route));
if (_history.lastIndexOf(route) <= _currentPosition)
popRoute(route);
}
void _handleRemoveRoute(Route route) {
assert(_history.contains(route));
setState(() {
_history.remove(route);
});
}
Widget build(BuildContext context) { Widget build(BuildContext context) {
List<Widget> visibleRoutes = new List<Widget>(); List<Widget> visibleRoutes = new List<Widget>();
bool alreadyInsertModalBarrier = false; bool alreadyInsertModalBarrier = false;
...@@ -132,20 +152,6 @@ class NavigatorState extends State<Navigator> { ...@@ -132,20 +152,6 @@ class NavigatorState extends State<Navigator> {
assert(!route.modal); assert(!route.modal);
continue; continue;
} }
route.ensurePerformance(
direction: (i <= _currentPosition) ? AnimationDirection.forward : AnimationDirection.reverse
);
route._onDismissed = () {
assert(_history.contains(route));
if (_history.lastIndexOf(route) <= _currentPosition)
popRoute(route);
};
route._onRemoveRoute = () {
assert(_history.contains(route));
setState(() {
_history.remove(route);
});
};
visibleRoutes.add( visibleRoutes.add(
new KeyedSubtree( new KeyedSubtree(
key: new ObjectKey(route), key: new ObjectKey(route),
...@@ -171,11 +177,14 @@ class NavigatorState extends State<Navigator> { ...@@ -171,11 +177,14 @@ class NavigatorState extends State<Navigator> {
abstract class Route { abstract class Route {
Route() {
_performance = createPerformance();
}
PerformanceView get performance => _performance?.view; PerformanceView get performance => _performance?.view;
Performance _performance; Performance _performance;
NotificationCallback _onDismissed; _RouteCallback _onDismissed;
NotificationCallback _onRemoveRoute; _RouteCallback _onRemoveRoute;
Performance createPerformance() { Performance createPerformance() {
Duration duration = transitionDuration; Duration duration = transitionDuration;
...@@ -184,26 +193,15 @@ abstract class Route { ...@@ -184,26 +193,15 @@ abstract class Route {
..addStatusListener((PerformanceStatus status) { ..addStatusListener((PerformanceStatus status) {
if (status == PerformanceStatus.dismissed) { if (status == PerformanceStatus.dismissed) {
if (_onDismissed != null) if (_onDismissed != null)
_onDismissed(); _onDismissed(this);
if (_onRemoveRoute != null) if (_onRemoveRoute != null)
_onRemoveRoute(); _onRemoveRoute(this);
} }
}); });
} }
return null; return null;
} }
void ensurePerformance({ AnimationDirection direction }) {
assert(direction != null);
if (_performance == null)
_performance = createPerformance();
if (_performance != null) {
PerformanceStatus desiredStatus = direction == AnimationDirection.forward ? PerformanceStatus.forward : PerformanceStatus.reverse;
if (_performance.status != desiredStatus)
_performance.play(direction);
}
}
/// If hasContent is true, then the route represents some on-screen state. /// If hasContent is true, then the route represents some on-screen state.
/// ///
/// If hasContent is false, then no performance will be created, and the values of /// If hasContent is false, then no performance will be created, and the values of
...@@ -262,9 +260,15 @@ abstract class Route { ...@@ -262,9 +260,15 @@ abstract class Route {
bool get isActuallyOpaque => (performance == null || _performance.isCompleted) && opaque; bool get isActuallyOpaque => (performance == null || _performance.isCompleted) && opaque;
Widget build(NavigatorState navigator, PerformanceView nextRoutePerformance); Widget build(NavigatorState navigator, PerformanceView nextRoutePerformance);
void didPush() {
_performance?.forward();
}
void didPop([dynamic result]) { void didPop([dynamic result]) {
_performance?.reverse();
if (performance == null && _onRemoveRoute != null) if (performance == null && _onRemoveRoute != null)
_onRemoveRoute(); _onRemoveRoute(this);
} }
String toString() => '$runtimeType()'; String toString() => '$runtimeType()';
......
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