We know how easy it is to navigate from one route to another in Flutter. We just need to do push and pop.

To push:

Navigator.push(

context,

MaterialPageRoute(builder: (context) => SecondRoute()),

);

To pop:

Navigator.pop(context);

That’s it. BUT… It’s very boring, there is no animation at all 😦 .

At Winkl when we started playing with animations we realized that page transition can really make your UI beautiful. If you want to have a slide transition like iOS you use CupertinoPageRoute. That’s it, nothing else.

Navigator.push(

context, CupertinoPageRoute(builder: (context) => Screen2()))

But for custom transition Flutter provides different transition widgets. Let’s see how we can use them.

We know that Navigator.push takes two arguments (BuildContext context, Route<T> route). We can create our own custom page route with some transition animation. Let’s start with something simple like a slide transition.

We will extend the PageRouteBuilder and define the transitionsBuilder which will return SlideTransition widget. The SlideTransition widget takes the position of type Animation<Offset>. We will use Tween<Offset> to give begin and end offset.

import 'package:flutter/material.dart'; class SlideRightRoute extends PageRouteBuilder {

final Widget page;

SlideRightRoute({this.page})

: super(

pageBuilder: (

BuildContext context,

Animation<double> animation,

Animation<double> secondaryAnimation,

) =>

page,

transitionsBuilder: (

BuildContext context,

Animation<double> animation,

Animation<double> secondaryAnimation,

Widget child,

) =>

SlideTransition(

position: Tween<Offset>(

begin: const Offset(-1, 0),

end: Offset.zero,

).animate(animation),

child: child,

),

);

}

We can now use SlideRightRoute instead of MaterialPageRoute like this.

Navigator.push(context, SlideRightRoute(page: Screen2()))

The result is…

Pretty easy, isn’t it? You can change the direction of the slide transition by changing the offset.

Scale Transition animates the scale of a transformed widget. You can also change how the animation comes in by changing the curves of CurvedAnimation. In the below example I have used Curves.fastOutSlowIn.

import 'package:flutter/material.dart'; class ScaleRoute extends PageRouteBuilder {

final Widget page;

ScaleRoute({this.page})

: super(

pageBuilder: (

BuildContext context,

Animation<double> animation,

Animation<double> secondaryAnimation,

) =>

page,

transitionsBuilder: (

BuildContext context,

Animation<double> animation,

Animation<double> secondaryAnimation,

Widget child,

) =>

ScaleTransition(

scale: Tween<double>(

begin: 0.0,

end: 1.0,

).animate(

CurvedAnimation(

parent: animation,

curve: Curves.fastOutSlowIn,

),

),

child: child,

),

);

}

The result is…

Rotation transition animates the rotation of a widget. You can also provide transitionDuration to your PageRouteBuilder.

import 'package:flutter/material.dart'; class RotationRoute extends PageRouteBuilder {

final Widget page;

RotationRoute({this.page})

: super(

pageBuilder: (

BuildContext context,

Animation<double> animation,

Animation<double> secondaryAnimation,

) =>

page,

transitionDuration: Duration(seconds: 1),

transitionsBuilder: (

BuildContext context,

Animation<double> animation,

Animation<double> secondaryAnimation,

Widget child,

) =>

RotationTransition(

turns: Tween<double>(

begin: 0.0,

end: 1.0,

).animate(

CurvedAnimation(

parent: animation,

curve: Curves.linear,

),

),

child: child,

),

);

}

The result is…

import 'package:flutter/material.dart'; class SizeRoute extends PageRouteBuilder {

final Widget page;

SizeRoute({this.page})

: super(

pageBuilder: (

BuildContext context,

Animation<double> animation,

Animation<double> secondaryAnimation,

) =>

page,

transitionsBuilder: (

BuildContext context,

Animation<double> animation,

Animation<double> secondaryAnimation,

Widget child,

) =>

Align(

child: SizeTransition(

sizeFactor: animation,

child: child,

),

),

);

}

The result is…

import 'package:flutter/material.dart'; class FadeRoute extends PageRouteBuilder {

final Widget page;

FadeRoute({this.page})

: super(

pageBuilder: (

BuildContext context,

Animation<double> animation,

Animation<double> secondaryAnimation,

) =>

page,

transitionsBuilder: (

BuildContext context,

Animation<double> animation,

Animation<double> secondaryAnimation,

Widget child,

) =>

FadeTransition(

opacity: animation,

child: child,

),

);

}

The result is…

Great!! We have seen all the basic transitions.