1// Copyright 2014 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5/// @docImport 'navigator.dart';
6library;
7
8import 'basic.dart';
9import 'framework.dart';
10import 'routes.dart';
11
12/// A modal route that replaces the entire screen.
13///
14/// The [PageRouteBuilder] subclass provides a way to create a [PageRoute] using
15/// callbacks rather than by defining a new class via subclassing.
16///
17/// If `barrierDismissible` is true, then pressing the escape key on the keyboard
18/// will cause the current route to be popped with null as the value.
19///
20/// See also:
21///
22/// * [Route], which documents the meaning of the `T` generic type argument.
23abstract class PageRoute<T> extends ModalRoute<T> {
24 /// Creates a modal route that replaces the entire screen.
25 PageRoute({
26 super.settings,
27 super.requestFocus,
28 super.traversalEdgeBehavior,
29 super.directionalTraversalEdgeBehavior,
30 this.fullscreenDialog = false,
31 this.allowSnapshotting = true,
32 bool barrierDismissible = false,
33 }) : _barrierDismissible = barrierDismissible;
34
35 /// {@template flutter.widgets.PageRoute.fullscreenDialog}
36 /// Whether this page route is a full-screen dialog.
37 ///
38 /// In Material and Cupertino, being fullscreen has the effects of making
39 /// the app bars have a close button instead of a back button. On
40 /// iOS, dialogs transitions animate differently and are also not closeable
41 /// with the back swipe gesture.
42 /// {@endtemplate}
43 @override
44 final bool fullscreenDialog;
45
46 @override
47 final bool allowSnapshotting;
48
49 @override
50 bool get opaque => true;
51
52 @override
53 bool get barrierDismissible => _barrierDismissible;
54 final bool _barrierDismissible;
55
56 @override
57 bool canTransitionTo(TransitionRoute<dynamic> nextRoute) => nextRoute is PageRoute;
58
59 @override
60 bool canTransitionFrom(TransitionRoute<dynamic> previousRoute) => previousRoute is PageRoute;
61
62 @override
63 bool get popGestureEnabled {
64 // Fullscreen dialogs aren't dismissible by back swipe.
65 return !fullscreenDialog && super.popGestureEnabled;
66 }
67}
68
69Widget _defaultTransitionsBuilder(
70 BuildContext context,
71 Animation<double> animation,
72 Animation<double> secondaryAnimation,
73 Widget child,
74) {
75 return child;
76}
77
78/// A utility class for defining one-off page routes in terms of callbacks.
79///
80/// Callers must define the [pageBuilder] function which creates the route's
81/// primary contents. To add transitions define the [transitionsBuilder] function.
82///
83/// The `T` generic type argument corresponds to the type argument of the
84/// created [Route] objects.
85///
86/// See also:
87///
88/// * [Route], which documents the meaning of the `T` generic type argument.
89class PageRouteBuilder<T> extends PageRoute<T> {
90 /// Creates a route that delegates to builder callbacks.
91 PageRouteBuilder({
92 super.settings,
93 super.requestFocus,
94 required this.pageBuilder,
95 this.transitionsBuilder = _defaultTransitionsBuilder,
96 this.transitionDuration = const Duration(milliseconds: 300),
97 this.reverseTransitionDuration = const Duration(milliseconds: 300),
98 this.opaque = true,
99 this.barrierDismissible = false,
100 this.barrierColor,
101 this.barrierLabel,
102 this.maintainState = true,
103 super.fullscreenDialog,
104 super.allowSnapshotting = true,
105 });
106
107 /// {@template flutter.widgets.pageRouteBuilder.pageBuilder}
108 /// Used build the route's primary contents.
109 ///
110 /// See [ModalRoute.buildPage] for complete definition of the parameters.
111 /// {@endtemplate}
112 final RoutePageBuilder pageBuilder;
113
114 /// {@template flutter.widgets.pageRouteBuilder.transitionsBuilder}
115 /// Used to build the route's transitions.
116 ///
117 /// See [ModalRoute.buildTransitions] for complete definition of the parameters.
118 /// {@endtemplate}
119 ///
120 /// The default transition is a jump cut (i.e. no animation).
121 final RouteTransitionsBuilder transitionsBuilder;
122
123 @override
124 final Duration transitionDuration;
125
126 @override
127 final Duration reverseTransitionDuration;
128
129 @override
130 final bool opaque;
131
132 @override
133 final bool barrierDismissible;
134
135 @override
136 final Color? barrierColor;
137
138 @override
139 final String? barrierLabel;
140
141 @override
142 final bool maintainState;
143
144 @override
145 Widget buildPage(
146 BuildContext context,
147 Animation<double> animation,
148 Animation<double> secondaryAnimation,
149 ) {
150 return pageBuilder(context, animation, secondaryAnimation);
151 }
152
153 @override
154 Widget buildTransitions(
155 BuildContext context,
156 Animation<double> animation,
157 Animation<double> secondaryAnimation,
158 Widget child,
159 ) {
160 return transitionsBuilder(context, animation, secondaryAnimation, child);
161 }
162}
163