Page Transitions
Loading preview
Starting the Flutter app
Fade, slide, scale, and rotation transition showcase
import 'package:flutter/material.dart';
class PageTransitions extends StatelessWidget {
const PageTransitions({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Page Transitions')),
body: ListView(
padding: const EdgeInsets.all(16),
children: [
_TransitionButton(
label: 'Fade',
onTap: () => Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (_, _, _) => const _DemoPage(title: 'Fade'),
transitionsBuilder: (_, animation, _, child) =>
FadeTransition(opacity: animation, child: child),
),
),
),
_TransitionButton(
label: 'Slide',
onTap: () => Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (_, _, _) => const _DemoPage(title: 'Slide'),
transitionsBuilder: (_, animation, _, child) => SlideTransition(
position: Tween<Offset>(
begin: const Offset(1, 0),
end: Offset.zero,
).animate(animation),
child: child,
),
),
),
),
_TransitionButton(
label: 'Scale',
onTap: () => Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (_, _, _) => const _DemoPage(title: 'Scale'),
transitionsBuilder: (_, animation, _, child) =>
ScaleTransition(scale: animation, child: child),
),
),
),
_TransitionButton(
label: 'Rotation',
onTap: () => Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (_, _, _) => const _DemoPage(title: 'Rotation'),
transitionsBuilder: (_, animation, _, child) =>
RotationTransition(turns: animation, child: child),
),
),
),
],
),
);
}
}
class _TransitionButton extends StatelessWidget {
final String label;
final VoidCallback onTap;
const _TransitionButton({required this.label, required this.onTap});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(bottom: 8),
child: FilledButton(onPressed: onTap, child: Text(label)),
);
}
}
class _DemoPage extends StatelessWidget {
final String title;
const _DemoPage({required this.title});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(title)),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(title, style: Theme.of(context).textTheme.headlineMedium),
const SizedBox(height: 16),
FilledButton(
onPressed: () => Navigator.pop(context),
child: const Text('Back'),
),
],
),
),
);
}
}
Add it to your project
Copies the Dart source into your app, so you own it. Flutter SDK only, no extra packages.
First time? Run dart pub global activate fluttertemplates_dev, or read the CLI guide.
How it works
Four _TransitionButtons each push a PageRouteBuilder to the same _DemoPage, differing only in transitionsBuilder: FadeTransition, SlideTransition, ScaleTransition and RotationTransition. They run on the route’s default duration with the raw linear animation, no curve applied. Passing animation straight to turns spins the page one full revolution on the way in, then backwards on pop.
Adapting it
- Extract the repeated
PageRouteBuilderinto a helper taking a page and a transition, and call it from your router. - Wrap
animationin aCurvedAnimationfor softer motion, and settransitionDurationto change timing. - Replace
_DemoPagewith your destination screen.