Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
e5aa1b1e
Commit
e5aa1b1e
authored
Jan 25, 2017
by
Hans Muller
Committed by
GitHub
Jan 25, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added PageRouteBuilder (#7632)
parent
94fab77b
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
139 additions
and
68 deletions
+139
-68
navigator.dart
packages/flutter/lib/src/widgets/navigator.dart
+64
-47
pages.dart
packages/flutter/lib/src/widgets/pages.dart
+69
-0
navigator_test.dart
packages/flutter/test/widgets/navigator_test.dart
+6
-21
No files found.
packages/flutter/lib/src/widgets/navigator.dart
View file @
e5aa1b1e
...
...
@@ -289,7 +289,7 @@ typedef bool RoutePredicate(Route<dynamic> route);
/// want to appear on the screen. For example:
///
/// ```dart
/// Navigator.of(context).push(new MaterialPageRoute(
/// Navigator.of(context).push(new MaterialPageRoute
<Null>
(
/// builder: (BuildContext context) {
/// return new Scaffold(
/// appBar: new AppBar(title: new Text('My Page')),
...
...
@@ -334,7 +334,7 @@ typedef bool RoutePredicate(Route<dynamic> route);
/// ```dart
/// void main() {
/// runApp(new MaterialApp(
/// home: new MyAppHome(),
/// home: new MyAppHome(),
// becomes the route named '/'
/// routes: <String, WidgetBuilder> {
/// '/a': (BuildContext context) => new MyPage(title: 'page A'),
/// '/b': (BuildContext context) => new MyPage(title: 'page B'),
...
...
@@ -352,7 +352,39 @@ typedef bool RoutePredicate(Route<dynamic> route);
/// The app's home page route is named '/' by default and other routes are
/// given pathnames by convention.
///
/// ### Defining a popup route
/// ### Routes can return a value
///
/// When a route is pushed to ask the user for a value, the value can be
/// returned via the [pop] method's result parameter.
///
/// Methods that push a route return a Future. The Future resolves when
/// the route is popped and the Future's value is the [pop] method's result
/// parameter.
///
/// For example if we wanted to ask the user to press 'OK' to confirm an
/// operation we could `await` the result of [Navigator.push]:
///
/// ```
/// bool value = await Navigator.of(context).push(new MaterialPageRoute<bool>(
/// builder: (BuildContext context) {
/// return new Center(
/// child: new FlatButton(
/// child: new Text('OK'),
/// onPressed: () { Navigator.of(context).pop(true); }
/// ),
/// );
/// }
/// ));
/// ```
/// If the user presses 'OK' then value will be true. If the user backs
/// out of the route, for example by pressing the Scaffold's back button,
/// the value will be null.
///
/// When a route is used to return a value, the route's type parameter
/// must match the type of [pop]'s result. That's why we've used
/// `MaterialPageRoute<bool>` instead of `MaterialPageRoute<Null>`.
///
/// ### Popup routes
///
/// Routes don't have to obscure the entire screen. [PopupRoute]s cover
/// the screen with a barrierColor that can be only partially opaque to
...
...
@@ -360,40 +392,34 @@ typedef bool RoutePredicate(Route<dynamic> route);
/// because they block input to the widgets below.
///
/// There are functions which create and show popup routes. For
/// example: [showDialog], [showMenu], and [showBottomSheet]. There are also
/// widgets which create popup routes, like [PopupMenuButton] and
/// [DropdownButton]. These functions and widgets create internal
/// subclasses of PopupRoute and use the Naviagator's push and pop methods
/// to show and dismiss them.
/// example: [showDialog], [showMenu], and [showBottomSheet]. These
/// functions return their pushed route's Future as described above.
/// Callers can await the returned value to take an action when the
/// route is popped, or to discover the route's value.
///
/// You can create your own subclass of [PopupRoute] to control the animated
/// transition employed to show the route, as well as the color and
/// behavior of the route's modal barrier. Here's an example that rotates
/// and fades its child when the route appears or disappears.
/// There are also widgets which create popup routes, like [PopupMenuButton] and
/// [DropdownButton]. These widgets create internal subclasses of PopupRoute
/// and use the Naviagator's push and pop methods to show and dismiss them.
///
/// ```dart
/// class _MyPopupRoute extends PopupRoute<Null> {
/// _MyPopupRoute({ this.child, this.color });
/// ### Custom routes
///
/// final Widget child;
/// final Color color;
/// You can create your own subclass of one the widget library route classes
/// like [PopupRoute], [ModalRoute], or [PageRoute], to control the animated
/// transition employed to show the route, the color and behavior of the route's
/// modal barrier, and other aspects of the route.
///
/// @override
/// Duration get transitionDuration => const Duration(milliseconds: 500);
/// The PageRouteBuilder class makes it possible to define a custom route
/// in terms of callbacks. Here's an example that rotates and fades its child
/// when the route appears or disappears. This route does not obscure the entire
/// screen because it specifies `opaque: false`, just as a popup route does.
///
/// @override
/// bool get barrierDismissable => true;
///
/// @override
/// Color get barrierColor => color;
///
/// @override
/// Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> forwardAnimation) {
/// return child;
/// }
///
/// @override
/// Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> forwardAnimation, Widget child) {
/// ```dart
/// Navigator.of(context).push(new PageRouteBuilder(
/// opaque: false,
/// pageBuilder: (BuildContext context, _, __) {
/// return new Center(child: new Text('My PageRoute'));
/// },
/// transitionsBuilder: (_, Animation<double> animation, __, Widget child) {
/// return new FadeTransition(
/// opacity: animation,
/// child: new RotationTransition(
...
...
@@ -402,23 +428,14 @@ typedef bool RoutePredicate(Route<dynamic> route);
/// ),
/// );
/// }
/// }
/// ```
///
/// The PopupRoute is built in two parts, the "page" and the
/// "transitions". The page becomes a descendant of the child passed to
/// the `buildTransitions` method. To show a route defined this way, we
/// just pass an instance of our [PopupRoute] subclass to
/// [Navigator.push]:
///
/// ```dart
/// Navigator.of(context).push(new _MyPopupRoute(
/// color: Theme.of(context).primaryColor.withOpacity(0.15),
/// child: new Center(
/// child: new Text('My Popup'),
/// ),
/// ));
/// ```
/// The page route is built in two parts, the "page" and the
/// "transitions". The page becomes a descendant of the child passed to
/// the `buildTransitions` method. Typically the page is only built once,
/// because it doesn't depend on its animation parameters (elided with `_`
/// and `__` in this example). The transition is built on every frame
/// for its duration.
class
Navigator
extends
StatefulWidget
{
/// Creates a widget that maintains a stack-based history of child widgets.
///
...
...
packages/flutter/lib/src/widgets/pages.dart
View file @
e5aa1b1e
...
...
@@ -3,6 +3,7 @@
// found in the LICENSE file.
import
'basic.dart'
;
import
'framework.dart'
;
import
'navigator.dart'
;
import
'overlay.dart'
;
import
'routes.dart'
;
...
...
@@ -39,3 +40,71 @@ abstract class PageRoute<T> extends ModalRoute<T> {
overlay
.
insert
(
entry
);
}
}
/// Signature for the [PageRouteBuilder] function that builds the route's
/// primary contents.
///
/// See [ModalRoute.buildPage] for complete definition of the parameters.
typedef
Widget
RoutePageBuilder
(
BuildContext
context
,
Animation
<
double
>
animation
,
Animation
<
double
>
forwardAnimation
);
/// Signature for the [PageRouteBuilder] function that builds the route's
/// transitions.
///
/// See [ModalRoute.buildTransitions] for complete definition of the parameters.
typedef
Widget
RouteTransitionsBuilder
(
BuildContext
context
,
Animation
<
double
>
animation
,
Animation
<
double
>
forwardAnimation
,
Widget
child
);
Widget
_defaultTransitionsBuilder
(
BuildContext
context
,
Animation
<
double
>
animation
,
Animation
<
double
>
forwardAnimation
,
Widget
child
)
{
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.
class
PageRouteBuilder
<
T
>
extends
PageRoute
<
T
>
{
PageRouteBuilder
({
RouteSettings
settings:
const
RouteSettings
(),
this
.
pageBuilder
,
this
.
transitionsBuilder
:
_defaultTransitionsBuilder
,
this
.
transitionDuration
:
const
Duration
(
milliseconds:
300
),
this
.
opaque
:
true
,
this
.
barrierDismissable
:
false
,
this
.
barrierColor
:
null
,
this
.
maintainState
:
true
,
})
:
super
(
settings:
settings
)
{
assert
(
pageBuilder
!=
null
);
assert
(
transitionsBuilder
!=
null
);
assert
(
opaque
!=
null
);
assert
(
barrierDismissable
!=
null
);
assert
(
maintainState
!=
null
);
}
final
RoutePageBuilder
pageBuilder
;
final
RouteTransitionsBuilder
transitionsBuilder
;
@override
final
Duration
transitionDuration
;
@override
final
bool
opaque
;
@override
final
bool
barrierDismissable
;
@override
final
Color
barrierColor
;
@override
final
bool
maintainState
;
@override
Widget
buildPage
(
BuildContext
context
,
Animation
<
double
>
animation
,
Animation
<
double
>
forwardAnimation
)
{
return
pageBuilder
(
context
,
animation
,
forwardAnimation
);
}
@override
Widget
buildTransitions
(
BuildContext
context
,
Animation
<
double
>
animation
,
Animation
<
double
>
forwardAnimation
,
Widget
child
)
{
return
transitionsBuilder
(
context
,
animation
,
forwardAnimation
,
child
);
}
}
packages/flutter/test/widgets/navigator_test.dart
View file @
e5aa1b1e
...
...
@@ -89,26 +89,6 @@ class OnTapPage extends StatelessWidget {
}
}
class
StringRoute
extends
PageRoute
<
String
>
{
StringRoute
(
RouteSettings
settings
,
this
.
builder
)
:
super
(
settings:
settings
);
final
WidgetBuilder
builder
;
@override
bool
get
maintainState
=>
true
;
@override
Duration
get
transitionDuration
=>
const
Duration
(
milliseconds:
300
);
@override
Color
get
barrierColor
=>
null
;
@override
Widget
buildPage
(
BuildContext
context
,
Animation
<
double
>
__
,
Animation
<
double
>
___
)
{
return
builder
(
context
);
}
}
void
main
(
)
{
testWidgets
(
'Can navigator navigate to and from a stateful widget'
,
(
WidgetTester
tester
)
async
{
final
Map
<
String
,
WidgetBuilder
>
routes
=
<
String
,
WidgetBuilder
>{
...
...
@@ -313,7 +293,12 @@ void main() {
await
tester
.
pumpWidget
(
new
MaterialApp
(
onGenerateRoute:
(
RouteSettings
settings
)
{
return
new
StringRoute
(
settings
,
(
BuildContext
context
)
=>
routes
[
settings
.
name
](
context
));
return
new
PageRouteBuilder
<
String
>(
settings:
settings
,
pageBuilder:
(
BuildContext
context
,
Animation
<
double
>
_
,
Animation
<
double
>
__
)
{
return
routes
[
settings
.
name
](
context
);
},
);
}
));
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment