Fix #721 Dialogs should appear in place rather than animating in from bottom
This commit is contained in:
parent
dda253bb29
commit
1c06ea17a3
@ -4,6 +4,8 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:sky/animation/animated_value.dart';
|
||||
import 'package:sky/animation/curves.dart';
|
||||
import 'package:sky/theme/colors.dart' as colors;
|
||||
import 'package:sky/widgets/basic.dart';
|
||||
import 'package:sky/widgets/default_text_style.dart';
|
||||
@ -12,6 +14,7 @@ import 'package:sky/widgets/material.dart';
|
||||
import 'package:sky/widgets/navigator.dart';
|
||||
import 'package:sky/widgets/scrollable.dart';
|
||||
import 'package:sky/widgets/theme.dart';
|
||||
import 'package:sky/widgets/transitions.dart';
|
||||
|
||||
typedef Widget DialogBuilder(Navigator navigator);
|
||||
|
||||
@ -107,6 +110,47 @@ class Dialog extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
class DialogRoute extends RouteBase {
|
||||
DialogRoute({ this.completer, this.builder });
|
||||
|
||||
final Completer completer;
|
||||
final RouteBuilder builder;
|
||||
|
||||
Widget build(Navigator navigator, RouteBase route) => builder(navigator, route);
|
||||
bool get isOpaque => false;
|
||||
|
||||
void popState([dynamic result]) {
|
||||
completer.complete(result);
|
||||
}
|
||||
|
||||
TransitionBase buildTransition({ Key key }) => new DialogTransition(key: key);
|
||||
}
|
||||
|
||||
const Duration _kTransitionDuration = const Duration(milliseconds: 150);
|
||||
class DialogTransition extends TransitionBase {
|
||||
DialogTransition({
|
||||
Key key,
|
||||
Widget child,
|
||||
Direction direction,
|
||||
Function onDismissed,
|
||||
Function onCompleted
|
||||
}): super(key: key,
|
||||
child: child,
|
||||
duration: _kTransitionDuration,
|
||||
direction: direction,
|
||||
onDismissed: onDismissed,
|
||||
onCompleted: onCompleted);
|
||||
|
||||
Widget buildWithChild(Widget child) {
|
||||
return new FadeTransition(
|
||||
performance: performance,
|
||||
direction: direction,
|
||||
opacity: new AnimatedValue<double>(0.0, end: 1.0, curve: easeOut),
|
||||
child: child
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future showDialog(Navigator navigator, DialogBuilder builder) {
|
||||
Completer completer = new Completer();
|
||||
navigator.push(new DialogRoute(
|
||||
|
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:sky/animation/animated_value.dart';
|
||||
import 'package:sky/animation/animation_performance.dart';
|
||||
import 'package:sky/animation/curves.dart';
|
||||
@ -17,6 +15,7 @@ abstract class RouteBase {
|
||||
Widget build(Navigator navigator, RouteBase route);
|
||||
bool get isOpaque;
|
||||
void popState([dynamic result]) { assert(result == null); }
|
||||
TransitionBase buildTransition({ Key key });
|
||||
}
|
||||
|
||||
class Route extends RouteBase {
|
||||
@ -27,20 +26,7 @@ class Route extends RouteBase {
|
||||
|
||||
Widget build(Navigator navigator, RouteBase route) => builder(navigator, route);
|
||||
bool get isOpaque => true;
|
||||
}
|
||||
|
||||
class DialogRoute extends RouteBase {
|
||||
DialogRoute({ this.completer, this.builder });
|
||||
|
||||
final Completer completer;
|
||||
final RouteBuilder builder;
|
||||
|
||||
Widget build(Navigator navigator, RouteBase route) => builder(navigator, route);
|
||||
bool get isOpaque => false;
|
||||
|
||||
void popState([dynamic result]) {
|
||||
completer.complete(result);
|
||||
}
|
||||
TransitionBase buildTransition({ Key key }) => new SlideUpFadeTransition(key: key);
|
||||
}
|
||||
|
||||
class RouteState extends RouteBase {
|
||||
@ -58,32 +44,30 @@ class RouteState extends RouteBase {
|
||||
if (callback != null)
|
||||
callback(this);
|
||||
}
|
||||
|
||||
TransitionBase buildTransition({ Key key }) {
|
||||
// Custom state routes shouldn't be asked to construct a transition
|
||||
assert(false);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(jackson): Refactor this into its own file
|
||||
// and support multiple transition types
|
||||
const Duration _kTransitionDuration = const Duration(milliseconds: 150);
|
||||
const Point _kTransitionStartPoint = const Point(0.0, 75.0);
|
||||
class Transition extends TransitionBase {
|
||||
Transition({
|
||||
class SlideUpFadeTransition extends TransitionBase {
|
||||
SlideUpFadeTransition({
|
||||
Key key,
|
||||
Widget child,
|
||||
Direction direction,
|
||||
Function onDismissed,
|
||||
Function onCompleted,
|
||||
this.interactive
|
||||
Function onCompleted
|
||||
}): super(key: key,
|
||||
child: child,
|
||||
duration: _kTransitionDuration,
|
||||
direction: direction,
|
||||
onDismissed: onDismissed,
|
||||
onCompleted: onCompleted);
|
||||
bool interactive;
|
||||
|
||||
void syncFields(Transition source) {
|
||||
interactive = source.interactive;
|
||||
super.syncFields(source);
|
||||
}
|
||||
|
||||
Widget buildWithChild(Widget child) {
|
||||
// TODO(jackson): Hit testing should ignore transform
|
||||
@ -201,22 +185,19 @@ class Navigator extends StatefulComponent {
|
||||
}
|
||||
if (child == null)
|
||||
continue;
|
||||
Transition transition = new Transition(
|
||||
key: new Key.fromObjectIdentity(historyEntry),
|
||||
child: child,
|
||||
direction: (i <= state.historyIndex) ? Direction.forward : Direction.reverse,
|
||||
interactive: (i == state.historyIndex),
|
||||
onDismissed: () {
|
||||
TransitionBase transition = historyEntry.route.buildTransition(key: new Key.fromObjectIdentity(historyEntry))
|
||||
..child = child
|
||||
..direction = (i <= state.historyIndex) ? Direction.forward : Direction.reverse
|
||||
..onDismissed = () {
|
||||
setState(() {
|
||||
state.history.remove(historyEntry);
|
||||
});
|
||||
},
|
||||
onCompleted: () {
|
||||
}
|
||||
..onCompleted = () {
|
||||
setState(() {
|
||||
historyEntry.fullyOpaque = historyEntry.route.isOpaque;
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
visibleRoutes.add(transition);
|
||||
}
|
||||
return new Focus(child: new Stack(visibleRoutes));
|
||||
|
@ -8,6 +8,8 @@ import 'package:sky/animation/animated_value.dart';
|
||||
import 'package:sky/widgets/basic.dart';
|
||||
import 'package:vector_math/vector_math.dart';
|
||||
|
||||
export 'package:sky/animation/direction.dart' show Direction;
|
||||
|
||||
dynamic _maybe(AnimatedValue x) => x != null ? x.value : null;
|
||||
|
||||
// A helper class to anchor widgets to one another. Pass an instance of this to
|
||||
|
Loading…
x
Reference in New Issue
Block a user