Navigate to a new screen in Flutter
Navigate to next screen with back using Navigator.push()
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),);
Navigate to next screen without back using Navigator.pushReplacement()
Navigator.pushReplacement(
context,MaterialPageRoute(builder: (context) => SecondRoute()),);
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => NextScreenName()));
}
Navigate to a new screen:
Navigator.of(context).push(MaterialPageRoute(builder: (context) => NewScreen()));
where context
is the BuildContext of a widget and NewScreen
is the name of the second widget layout.
Code
main.dart
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(primarySwatch: Colors.blue),
home: HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Home Screen')),
body: Center(
child: ElevatedButton(
child: const Text(
'Navigate to a new screen >>',
style: TextStyle(fontSize: 24.0),
),
onPressed: () {
_navigateToNextScreen(context);
},
),
),
);
}
void _navigateToNextScreen(BuildContext context) {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => NewScreen()));
}
}
class NewScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('New Screen')),
body: const Center(
child: Text(
'This is a new screen',
style: TextStyle(fontSize: 24.0),
),
),
);
}
}
See also
- Documentation
- Navigator and Routes and Transitions... Oh, My! - Simon Lightfoot | Flutter Europe
To load new screens with Flutter pre-canned animations, use their respective transition classes. For example:
Container Transformation
Basically we have the first widget or screen transform into the next screen. For this we need to use OpenContainer
. The following code illustrates an item in a ListView transformed to its details page.
@override
Widget build(BuildContext context) {
return Card(
color: Colors.white,
elevation: 2.0,
child: OpenContainer(
transitionType: ContainerTransitionType.fadeThrough,
closedColor: Theme.of(context).cardColor,
closedElevation: 0.0,
openElevation: 4.0,
transitionDuration: Duration(milliseconds: 1500),
openBuilder: (BuildContext context, VoidCallback _) => THENEXTSCREEN(),
closedBuilder: (BuildContext _, VoidCallback openContainer) {
return ListTile(
leading: Icon(Icons.album),
title: Text("ITEM NAME"),
);
},
),
);
}
Shared Axis
This transition is similar to that in Tab or Stepper. We need SharedAxisTransition
, PageTransitionSwitcher
, along with a state to model transition between active and previous page. If we only switch between two pages we can use a simple boolean isFirstPage
for it. Here's the snippet with Provider as state management:
@override
Widget build(BuildContext context) {
return Consumer<YourState>(
builder: (context, state, child) {
return PageTransitionSwitcher(
duration: const Duration(milliseconds: 1500),
reverse: !state.isFirstPage, // STATE
transitionBuilder: (
Widget child,
Animation<double> animation,
Animation<double> secondaryAnimation,
) {
return SharedAxisTransition(
child: child,
animation: animation,
secondaryAnimation: secondaryAnimation,
transitionType: SharedAxisTransitionType.horizontal,
);
},
child: state.isFirstPage? FIRSTPAGE() : SECONDPAGE(), // STATE
);
},
);
}
Note that in all these scenarios we don't use Navigator and MaterialPageRoute. All these codes are derived from animations repo so you may want to check it out first.