Flutter Navigation: Getting Started
Learn about routes, navigation, and transitions for apps written using the Flutter cross-platform framework from Google. By Filip Babić.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Flutter Navigation: Getting Started
15 mins
Popping the Stack
Since navigation in the Flutter app is working like a stack of widgets, and you’ve pushed a new screen widget onto the stack, you’ll pop from the stack in order to go back.
Inside memberwidget.dart, add an IconButton
to MemberState
by updating build()
to add a Column
in place of just the Image:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(member.login),
),
body: Padding(
padding: EdgeInsets.all(16.0),
// Make child a Column here and add the IconButton
child: Column(
children: [
Image.network(member.avatarUrl),
IconButton(
icon: Icon(Icons.arrow_back, color: Colors.green, size: 48.0),
onPressed: () {
Navigator.pop(context);
})
])));
}
You’ve added the Column
in order to layout the Image
and an IconButton
vertically. For the IconButton
, you’ve set its onPressed
value to call Navigator
and pop the stack.
Build and run the app using F5, and you’ll be able to go back to the member list by tapping your new back arrow:
Returning a Value
Routes can return values. To see an example, add the following private async
method to MemberState
:
_showOKScreen(BuildContext context) async {
// 1, 2
bool value = await Navigator.push(context,
MaterialPageRoute<bool>(builder: (BuildContext context) {
return Padding(
padding: const EdgeInsets.all(32.0),
// 3
child: Column(children: [
GestureDetector(
child: Text('OK'),
// 4, 5
onTap: () {
Navigator.pop(context, true);
}),
GestureDetector(
child: Text('NOT OK'),
// 4, 5
onTap: () {
Navigator.pop(context, false);
})
]));
}));
// 6
var alert = AlertDialog(
content: Text((value != null && value)
? "OK was pressed"
: "NOT OK or BACK was pressed"),
actions: <Widget>[
FlatButton(
child: Text('OK'),
// 7
onPressed: () {
Navigator.pop(context);
})
],
);
// 8
showDialog(context: context, child: alert);
}
Here is what’s going on in this method:
- You push a new
MaterialPageRoute
onto the stack, this time with a type parameter ofbool
. The type parameter denotes the type you want to return when going back. - You use
await
when pushing the new route, which waits until the route is popped. - The route you push onto the stack has a
Column
that shows two text widgets with gesture detectors. - Tapping on the text widgets causes calls to
Navigator
to pop the new route off the stack. - In the calls to
pop()
, you pass a return value oftrue
if the user tapped the “OK” text on the screen, and false if the user tapped “NOT OK”. If the user presses the back button instead, the value returned isnull
. - You then create an
AlertDialog
to show the result returned from the route. - Note that the
AlertDialog
itself must be popped off the stack. - You call
showDialog()
to show the alert.
The primary points to note in the above are:
- The
bool
type parameter inMaterialPageRoute
, which you can replace with any other type you want coming back from the route - The fact that you pass the result back in the call to pop, for example,
Navigator.pop(context, true)
.
Next, inside MemberState
‘s build()
, add a RaisedButton that calls _showOKScreen()
as another child of the Column
you added earlier:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(member.login),
),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Column(children: [
Image.network(member.avatarUrl),
IconButton(
icon: Icon(Icons.arrow_back, color: Colors.green, size: 48.0),
onPressed: () {
Navigator.pop(context);
}),
// Add this raised button
RaisedButton(
child: Text('PRESS ME'),
onPressed: () {
_showOKScreen(context);
})
])));
}
The RaisedButton you’ve added shows the new screen.
Hit F5 to build and run the app, tap the “PRESS ME” button, and then tap either “OK”, “NOT OK”, or the back button. You’ll get a result back from the new screen showing which of the results the user tapped:
Creating Custom Transitions
In order to give the navigation of your app a unique feel, you can create a custom transition. One way to do so is to use a class like PageRouteBuilder
that defines custom routes with callbacks.
Replace _pushMember()
in GHFlutterState
, with the following code, so that it pushes a new PageRouteBuilder
onto the stack:
_pushMember(Member member) {
// 1
Navigator.push(
context,
PageRouteBuilder(
opaque: true,
// 2
transitionDuration: const Duration(milliseconds: 1000),
// 3
pageBuilder: (BuildContext context, _, __) {
return MemberWidget(member);
},
// 4
transitionsBuilder:
(_, Animation<double> animation, __, Widget child) {
return FadeTransition(
opacity: animation,
child: RotationTransition(
turns: Tween<double>(begin: 0.0, end: 1.0).animate(animation),
child: child,
),
);
}));
}
Here you:
- Push a new
PageRouteBuilder
onto the stack. - Specify the duration using
transitionDuration
. - Create the
MemberWidget
screen usingpageBuilder
. - Use the
transitionsBuilder
to create fade and rotation transitions when showing the new route.
Hit F5 to build and run the app, and see your new transition in action:
Wow! That’s making me a little dizzy! :]
Where to Go From Here?
You can download the completed project using the Download Materials button at the top or bottom of the page.
This tutorial has just scratched the surface of navigation on Flutter. In future tutorials, we’ll dig even deeper, including looking more at modal navigation.
You can learn more about Flutter navigation by visiting:
- Navigation and Routing in the Flutter docs.
- The Navigator API docs.
As you’re reading the docs, check out in particular how to make named routes, which you call on a Navigator
using pushNamed()
.
Stay tuned for more Flutter tutorials and screencasts on our Flutter page!
Feel free to share your feedback, findings or ask any questions in the comments below or in the forums. I hoped you enjoyed learning about navigation with Flutter!