From 6eb137185a615d05524484ef0959c4838baa4f70 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Fri, 17 Jul 2015 09:38:22 -0700 Subject: [PATCH] Navigator improvements, avoid building invisible routes --- sky/sdk/example/widgets/navigation.dart | 10 ++++++++ sky/sdk/lib/widgets/navigator.dart | 31 +++++++++++++++++++++---- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/sky/sdk/example/widgets/navigation.dart b/sky/sdk/example/widgets/navigation.dart index c6168314cf506..0af68f7810668 100644 --- a/sky/sdk/example/widgets/navigation.dart +++ b/sky/sdk/example/widgets/navigation.dart @@ -68,6 +68,16 @@ List routes = [ class NavigationExampleApp extends App { NavigationState _navState = new NavigationState(routes); + void onBack() { + if (_navState.hasPrevious()) { + setState(() { + _navState.pop(); + }); + } else { + super.onBack(); + } + } + Widget build() { return new Flex([new Navigator(_navState)]); } diff --git a/sky/sdk/lib/widgets/navigator.dart b/sky/sdk/lib/widgets/navigator.dart index 99b5b87171d23..a9b11857388df 100644 --- a/sky/sdk/lib/widgets/navigator.dart +++ b/sky/sdk/lib/widgets/navigator.dart @@ -42,8 +42,8 @@ class RouteState extends RouteBase { // TODO(jackson): Refactor this into its own file // and support multiple transition types -const Duration _kTransitionDuration = const Duration(milliseconds: 200); -const Point _kTransitionStartPoint = const Point(0.0, 100.0); +const Duration _kTransitionDuration = const Duration(milliseconds: 150); +const Point _kTransitionStartPoint = const Point(0.0, 75.0); enum TransitionDirection { forward, reverse } class Transition extends AnimatedComponent { Transition({ @@ -51,12 +51,14 @@ class Transition extends AnimatedComponent { this.content, this.direction, this.onDismissed, + this.onCompleted, this.interactive }) : super(key: key); Widget content; TransitionDirection direction; bool interactive; Function onDismissed; + Function onCompleted; AnimatedType _position; AnimatedType _opacity; @@ -73,7 +75,8 @@ class Transition extends AnimatedComponent { _performance = new AnimationPerformance() ..duration = _kTransitionDuration ..variable = new AnimatedList([_position, _opacity]) - ..addListener(_checkDismissed); + ..addListener(_checkDismissed) + ..addListener(_checkCompleted); if (direction == TransitionDirection.reverse) _performance.progress = 1.0; watch(_performance); @@ -114,6 +117,17 @@ class Transition extends AnimatedComponent { } } + bool _completed = false; + void _checkCompleted() { + if (!_completed && + direction == TransitionDirection.forward && + _performance.isCompleted) { + if (onCompleted != null) + onCompleted(); + _completed = true; + } + } + Widget build() { Matrix4 transform = new Matrix4.identity() ..translate(_position.value.x, _position.value.y); @@ -133,6 +147,7 @@ class HistoryEntry { HistoryEntry({ this.route, this.key }); final RouteBase route; final int key; + bool transitionFinished = false; // TODO(jackson): Keep track of the requested transition } @@ -170,6 +185,7 @@ class NavigationState { if (historyIndex > 0) { HistoryEntry entry = history[historyIndex]; entry.route.popState(); + entry.transitionFinished = false; historyIndex--; } } @@ -217,7 +233,9 @@ class Navigator extends StatefulComponent { Widget build() { List visibleRoutes = new List(); for (int i = 0; i < state.history.length; i++) { - // TODO(jackson): Avoid building routes that are not visible + // Avoid building routes that are not visible + if (i + 1 < state.history.length && state.history[i + 1].transitionFinished) + continue; HistoryEntry historyEntry = state.history[i]; Widget content = historyEntry.route.build(this, historyEntry.route); if (i == 0) { @@ -235,6 +253,11 @@ class Navigator extends StatefulComponent { setState(() { state.history.remove(historyEntry); }); + }, + onCompleted: () { + setState(() { + historyEntry.transitionFinished = true; + }); } ); visibleRoutes.add(transition);