Flutter Navigation Basics
Moving between screens in your app
🧭 What is Navigation?
Navigation in Flutter allows users to move between different screens or pages in your app. Using Navigator, you can push new screens onto a stack and pop them off, creating smooth transitions and intuitive user flows.
// Simple navigation example
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondPage()),
);
Output:
Key Navigation Concepts
Push
Navigate to a new screen
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Page()),
)
Pop
Go back to previous screen
Navigator.pop(context);
Pass Data
Send data between screens
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Page(data: 'Hello'),
),
)
Return Data
Get data from popped screen
final result = await Navigator.push(...);
🔹 Basic Navigation - Push
Navigate to a new screen using Navigator.push:
import 'package:flutter/material.dart';
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('First Page')),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondPage()),
);
},
child: Text('Go to Second Page'),
),
),
);
}
}
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Second Page')),
body: Center(
child: Text('Welcome to Second Page!'),
),
);
}
}
Output:
🔹 Going Back - Pop
Return to the previous screen using Navigator.pop:
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Second Page')),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go Back'),
),
),
);
}
}
Output:
🔹 Passing Data Forward
Send data to the next screen through constructor:
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecondPage(
message: 'Hello from First Page!',
),
),
);
},
child: Text('Send Data'),
),
),
);
}
}
class SecondPage extends StatelessWidget {
final String message;
SecondPage({required this.message});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Second Page')),
body: Center(
child: Text(message),
),
);
}
}
Output (Second Page):
🔹 Returning Data Back
Get data back from a popped screen:
// First Page - Receiving data
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () async {
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondPage()),
);
print('Received: $result');
},
child: Text('Get Data from Second Page'),
),
),
);
}
}
// Second Page - Sending data back
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pop(context, 'Data from Second Page');
},
child: Text('Send Data Back'),
),
),
);
}
}
Output:
🔹 Navigation with Animation
Add custom transitions between screens:
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => SecondPage(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
const begin = Offset(1.0, 0.0);
const end = Offset.zero;
const curve = Curves.easeInOut;
var tween = Tween(begin: begin, end: end).chain(
CurveTween(curve: curve),
);
return SlideTransition(
position: animation.drive(tween),
child: child,
);
},
),
);
Output:
🔹 Replace Current Screen
Replace the current screen instead of stacking:
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => NewPage()),
);
// User cannot go back to previous screen
// Useful for login -> home transitions