Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between MaterialPageRoute and PageRouteBuilder

Tags:

flutter

To provide custom animations, I can either extend MaterialPageRoute or PageRouteBuilder and they both seem to do the same job. So, what's the difference between the two and which one should I use?

Here's the code snippet:

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ElevatedButton(
        onPressed: () => Navigator.push(context, Foo/BarRoute(Scaffold(appBar: AppBar()))),
        child: Text('Navigate'),
      ),
    );
  }
}

class FooRoute<T> extends MaterialPageRoute<T> {
  final Widget page;
  FooRoute(this.page) : super(builder: (_) => page);

  @override
  Widget buildTransitions(_, animation, __, ___) {
    return FadeTransition(opacity: animation, child: page);
  }
}

class BarRoute<T> extends PageRouteBuilder<T> {
  final Widget page;
  BarRoute(this.page) : super(pageBuilder: (_, __, ___) => page);

  @override
  Widget buildTransitions(_, animation, __, ___) {
    return FadeTransition(opacity: animation, child: page);
  }
}

The only difference I saw was on running the app on an iOS device where MaterialPageRoute tries to insert some iOSed type sliding animation in the background.

like image 225
iDecode Avatar asked Jun 01 '26 05:06

iDecode


1 Answers

The difference between MaterialPageRoute and PageRouteBuilder is that MaterialPageRoute already defines transition animations (animations which follow the Material design concept), while PageRouteBuilder is used to "expose" the in/out animation in a builder style.

Basically whenever you want a one-time animation you would use PageRouteBuilder. For example:

Navigator.push(
  context,
  PageRouteBuilder(
    pageBuilder: (
      context,
      animation,
      secondaryAnimation,
    ) {
      return const SecondRoute();
    },
    transitionsBuilder: (
      context,
      animation,
      secondaryAnimation,
      child,
    ) {
      return FadeTransition(
        opacity: animation,
        child: child,
      );
    },
  ),
);

When you want to define a custom transition animation that will be used across your app, the approach that will fit most would be to keep using MaterialPageRoute for your navigation. Most projects' navigation will look like:

Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => const SomeRoute()),
);

And define the custom animation using a PageTransitionBuilder in the MaterialApp's Theme

MaterialApp(
  title: 'Navigation Basics',
  theme: ThemeData(
    useMaterial3: true,
    pageTransitionsTheme: const PageTransitionsTheme(
      builders: <TargetPlatform, PageTransitionsBuilder>{
        TargetPlatform.android: MyCustomPageTransitionsBuilder(),
        TargetPlatform.iOS: MyCustomPageTransitionsBuilder(),
        TargetPlatform.linux: MyCustomPageTransitionsBuilder(),
        TargetPlatform.macOS: MyCustomPageTransitionsBuilder(),
      },
    ),
  ),

This way, because we used MaterialPageRoute, it will look up the widget tree for pageTransitionsTheme for the platform currently running and use the animation defined in MyCustomPageTransitionsBuilder

You can find a full example here.

If you want even more control, subclass PageRoute and use that class instead of MaterialPageRoute. Just remember to handle things like dialogs, and different platform types, etc.

like image 171
Alex.F Avatar answered Jun 02 '26 20:06

Alex.F



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!