Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

To move page transitions out of individual Flutter screens, define the motion where you create or configure a route. For a custom animation, use PageRouteBuilder: build the destination in pageBuilder and put the animation in transitionsBuilder. Your screens then describe page content, while route navigation controls how that content appears.

Why put transition logic at the route boundary?

A Navigator manages a stack of routes. When you push a route, that route determines how its page enters. Keeping motion in the route layer prevents each screen from carrying its own navigation animation and lets you reuse or change the transition without rewriting page widgets. See Flutter’s navigation overview and page-route animation recipe.

This does not require a new routing architecture. A custom route can still be pushed with Navigator; choose Router or a routing package when your app’s needs warrant it.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Build a reusable custom transition with PageRouteBuilder

PageRouteBuilder separates the destination page from its motion. The pageBuilder supplies the page, while transitionsBuilder receives the route’s primary animation, secondary animation, and page child. Flutter notes that the child remains stable throughout the transition, so it does not need to be rebuilt on every animation tick.

Route<void> buildSlideRoute(Widget page) {
  return PageRouteBuilder<void>(
    pageBuilder: (context, animation, secondaryAnimation) => page,
    transitionsBuilder: (context, animation, secondaryAnimation, child) {
      final offsetAnimation = Tween<Offset>(
        begin: const Offset(0, 1),
        end: Offset.zero,
      ).chain(
        CurveTween(curve: Curves.ease),
      ).animate(animation);

      return SlideTransition(
        position: offsetAnimation,
        child: child,
      );
    },
  );
}

Use the route factory when navigating, for example with Navigator.of(context).push(buildSlideRoute(const DetailsPage())). The Tween maps the route animation to positions; Offset(0, 1) to Offset.zero moves the incoming page upward from below the viewport by its own height. This is one possible direction and curve, not a universal convention.

Choose motion that fits the app

The same separation works with other transition widgets or animation values. Keep the destination in pageBuilder, use the provided child in the transition builder, and make the motion reusable as a route factory or route definition. That keeps visual behavior out of the page’s content and lifecycle.

When platform-standard transitions are a better fit

If you want familiar platform behavior rather than a bespoke effect, use the platform-specific route classes. MaterialPageRoute provides Material route behavior; CupertinoPageRoute provides an iOS-style horizontal slide and swipe-to-go-back gesture. Flutter also supports configuring transition builders through PageTransitionsTheme. See the MaterialPageRoute API, CupertinoPageRoute API, and PageTransitionsTheme API.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Builder names and imports can vary with Flutter SDK changes. In particular, Flutter moved CupertinoPageTransitionsBuilder to the Cupertino library; check the API documentation for your installed SDK before changing imports. The Flutter breaking changes index provides version context.

Keep navigation architecture separate from animation

Choose a routing approach based on how users reach pages, not just on how pages move. A simple stack can use Navigator whether its routes use standard or custom motion. Apps with more involved deep links or multiple navigators may need Flutter’s declarative Router API or a routing package such as go_router. Flutter describes Router-backed pages as deep-linkable, while routes added imperatively as pageless routes are not. Its navigation guidance also says named routes are not recommended for most applications because of their limitations. Read Flutter’s navigation and routing guidance before choosing a migration.

Account for Android predictive back

Android predictive back lets users preview where a back gesture will navigate before committing to or cancelling it. Because the system needs to know whether a route can pop before the gesture completes, represent that state ahead of time with PopScope, keep canPop synchronized with application state, and handle the result in onPopInvokedWithResult. Flutter’s migration guide deprecates the just-in-time cancellation pattern based on WillPopScope, which cannot provide that advance decision.

  1. Replace pop veto logic: use PopScope instead of WillPopScope and update canPop whenever the relevant app state changes.
  2. Handle the attempted pop: use onPopInvokedWithResult for work that depends on whether the route was popped.
  3. Configure Android where required: Flutter’s setup guidance says that for Android 13 or later, add android:enableOnBackInvokedCallback="true" to the application element in the Android manifest.
  4. Test on the target configuration: Android 14/API 34 enables predictive-back animations by default for supported system gestures, according to Flutter’s guide; behavior also depends on the route builder and app configuration.

Follow the Android predictive-back migration guide for the current setup and API details.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Check the Android transition default for your Flutter version

Do not assume every Flutter app has the same Android page transition. Flutter’s release note identifies stable Flutter 3.38.0 as the release where PredictiveBackPageTransitionsBuilder became the Android default in place of ZoomPageTransitionsBuilder. The normal transition uses FadeForwardsPageTransitionsBuilder when no predictive gesture is active; during the gesture, the route animation follows the gesture. An app that explicitly configures an older builder retains that choice and does not receive predictive-back route transitions through that builder.

Before changing behavior, check the Flutter SDK used to build the app and inspect its PageTransitionsTheme. The predictive-back page transitions change note documents the default change and its release context.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.