pages.dart 7.94 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5
import 'basic.dart';
6
import 'framework.dart';
7 8 9 10 11
import 'navigator.dart';
import 'routes.dart';

/// A modal route that replaces the entire screen.
abstract class PageRoute<T> extends ModalRoute<T> {
12
  /// Creates a modal route that replaces the entire screen.
13
  PageRoute({
14
    RouteSettings? settings,
15
    this.fullscreenDialog = false,
16
  }) : super(settings: settings);
17

18
  /// {@template flutter.widgets.pageRoute.fullscreenDialog}
19 20 21 22 23 24
  /// Whether this page route is a full-screen dialog.
  ///
  /// In Material and Cupertino, being fullscreen has the effects of making
  /// the app bars have a close button instead of a back button. On
  /// iOS, dialogs transitions animate differently and are also not closeable
  /// with the back swipe gesture.
25
  /// {@endtemplate}
26 27
  final bool fullscreenDialog;

28
  @override
29
  bool get opaque => true;
30 31

  @override
32
  bool get barrierDismissible => false;
33 34

  @override
35
  bool canTransitionTo(TransitionRoute<dynamic> nextRoute) => nextRoute is PageRoute;
36 37

  @override
38
  bool canTransitionFrom(TransitionRoute<dynamic> previousRoute) => previousRoute is PageRoute;
39
}
40

41
Widget _defaultTransitionsBuilder(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
42 43 44 45 46 47 48
  return child;
}

/// A utility class for defining one-off page routes in terms of callbacks.
///
/// Callers must define the [pageBuilder] function which creates the route's
/// primary contents. To add transitions define the [transitionsBuilder] function.
49 50 51 52
///
/// See also:
///
///  * [TransitionBuilderPage], which is a [Page] of this class.
53
class PageRouteBuilder<T> extends PageRoute<T> {
54
  /// Creates a route that delegates to builder callbacks.
55
  ///
56
  /// The [pageBuilder], [transitionsBuilder], [opaque], [barrierDismissible],
57
  /// [maintainState], and [fullscreenDialog] arguments must not be null.
58
  PageRouteBuilder({
59 60
    RouteSettings? settings,
    required this.pageBuilder,
61 62
    this.transitionsBuilder = _defaultTransitionsBuilder,
    this.transitionDuration = const Duration(milliseconds: 300),
63
    this.reverseTransitionDuration = const Duration(milliseconds: 300),
64 65
    this.opaque = true,
    this.barrierDismissible = false,
66
    this.barrierColor,
67
    this.barrierLabel,
68
    this.maintainState = true,
69
    bool fullscreenDialog = false,
70 71
  }) : assert(pageBuilder != null),
       assert(transitionsBuilder != null),
72
       assert(opaque != null),
73 74
       assert(barrierDismissible != null),
       assert(maintainState != null),
75 76
       assert(fullscreenDialog != null),
       super(settings: settings, fullscreenDialog: fullscreenDialog);
77

78
  /// {@template flutter.widgets.pageRouteBuilder.pageBuilder}
79 80 81
  /// Used build the route's primary contents.
  ///
  /// See [ModalRoute.buildPage] for complete definition of the parameters.
82
  /// {@endtemplate}
83
  final RoutePageBuilder pageBuilder;
84

85
  /// {@template flutter.widgets.pageRouteBuilder.transitionsBuilder}
86 87 88
  /// Used to build the route's transitions.
  ///
  /// See [ModalRoute.buildTransitions] for complete definition of the parameters.
89
  /// {@endtemplate}
90 91 92 93 94
  final RouteTransitionsBuilder transitionsBuilder;

  @override
  final Duration transitionDuration;

95 96 97
  @override
  final Duration reverseTransitionDuration;

98 99 100 101
  @override
  final bool opaque;

  @override
102
  final bool barrierDismissible;
103 104

  @override
105
  final Color? barrierColor;
106

107
  @override
108
  final String? barrierLabel;
109

110 111 112 113
  @override
  final bool maintainState;

  @override
114 115
  Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
    return pageBuilder(context, animation, secondaryAnimation);
116 117 118
  }

  @override
119 120
  Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
    return transitionsBuilder(context, animation, secondaryAnimation, child);
121
  }
122 123 124 125 126 127 128 129 130 131 132 133 134 135
}

/// A page that creates a [PageRoute] with customizable transition.
///
/// Similar to the [PageRouteBuilder], callers must define the [pageBuilder]
/// function which creates the route's primary contents. To add transitions
/// define the [transitionsBuilder] function.
///
/// See also:
///
///  * [PageRouteBuilder], which is a [PageRoute] version of this class.
class TransitionBuilderPage<T> extends Page<T> {
  /// Creates a [TransitionBuilderPage].
  const TransitionBuilderPage({
136
    required this.pageBuilder,
137 138
    this.transitionsBuilder = _defaultTransitionsBuilder,
    this.transitionDuration = const Duration(milliseconds: 300),
139
    this.reverseTransitionDuration = const Duration(milliseconds: 300),
140 141 142 143 144 145
    this.opaque = true,
    this.barrierDismissible = false,
    this.barrierColor,
    this.barrierLabel,
    this.maintainState = true,
    this.fullscreenDialog = false,
146 147 148
    LocalKey? key,
    String? name,
    Object? arguments,
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
  }) : assert(pageBuilder != null),
       assert(transitionsBuilder != null),
       assert(opaque != null),
       assert(barrierDismissible != null),
       assert(maintainState != null),
       assert(fullscreenDialog != null),
       super(key: key, name: name, arguments: arguments);

  /// {@macro flutter.widgets.pageRouteBuilder.pageBuilder}
  final RoutePageBuilder pageBuilder;

  /// {@macro flutter.widgets.pageRouteBuilder.transitionsBuilder}
  final RouteTransitionsBuilder transitionsBuilder;

  /// {@macro flutter.widgets.transitionRoute.transitionDuration}
  final Duration transitionDuration;

166 167 168
  /// {@macro flutter.widgets.transitionRoute.reverseTransitionDuration}
  final Duration reverseTransitionDuration;

169 170 171 172 173 174 175
  /// {@macro flutter.widgets.transitionRoute.opaque}
  final bool opaque;

  /// {@macro flutter.widgets.modalRoute.barrierDismissible}
  final bool barrierDismissible;

  /// {@macro flutter.widgets.modalRoute.barrierColor}
176 177 178 179 180 181
  ///
  /// See also:
  ///
  ///  * [barrierDismissible], which controls the behavior of the barrier when
  ///    tapped.
  ///  * [ModalBarrier], the widget that implements this feature.
182
  final Color? barrierColor;
183 184

  /// {@macro flutter.widgets.modalRoute.barrierLabel}
185 186 187 188 189 190
  ///
  /// See also:
  ///
  ///  * [barrierDismissible], which controls the behavior of the barrier when
  ///    tapped.
  ///  * [ModalBarrier], the widget that implements this feature.
191
  final String? barrierLabel;
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217

  /// {@macro flutter.widgets.modalRoute.maintainState}
  final bool maintainState;

  /// {@macro flutter.widgets.pageRoute.fullscreenDialog}
  final bool fullscreenDialog;

  @override
  Route<T> createRoute(BuildContext context) => _PageBasedPageRouteBuilder<T>(this);
}

// A page-based version of the [PageRouteBuilder].
//
// This class gets its builder and settings directly from the [TransitionBuilderPage],
// so that its content updates accordingly to the [TransitionBuilderPage].
class _PageBasedPageRouteBuilder<T> extends PageRoute<T>{
  _PageBasedPageRouteBuilder(
    TransitionBuilderPage<T> page,
  ) : assert(page != null),
       super(settings: page, fullscreenDialog: page.fullscreenDialog);

  TransitionBuilderPage<T> get _page => settings as TransitionBuilderPage<T>;

  @override
  Duration get transitionDuration => _page.transitionDuration;

218 219 220
  @override
  Duration get reverseTransitionDuration => _page.reverseTransitionDuration;

221 222 223 224 225 226 227
  @override
  bool get opaque => _page.opaque;

  @override
  bool get barrierDismissible => _page.barrierDismissible;

  @override
228
  Color? get barrierColor => _page.barrierColor;
229 230

  @override
231
  String? get barrierLabel => _page.barrierLabel;
232 233 234 235 236 237 238 239

  @override
  bool get maintainState => _page.maintainState;

  @override
  Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
    return _page.pageBuilder(context, animation, secondaryAnimation);
  }
240

241 242 243 244
  @override
  Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
    return _page.transitionsBuilder(context, animation, secondaryAnimation, child);
  }
245
}