A MaterialPageRoute component is provided in the Material component library, which can use route switching animation consistent with the platform style. For example, it will slide left and right on iOS and up and down on Android. Now, what should we do if we also want to use the left-right switching style on Android? A simple way is to directly use CupertinoPageRoute, such as:
Navigator.push(context, CupertinoPageRoute( builder: (context)=>PageB(), ));
Cupertino pageroute is an iOS style route switching component provided by Cupertino component library. It realizes left-right sliding switching. So how can we customize the route switching animation? The answer is PageRouteBuilder. Let's take a look at how to use PageRouteBuilder to customize the route switching animation. For example, we want to realize routing transition with fade in animation. The implementation code is as follows:
Navigator.push( context, PageRouteBuilder( transitionDuration: Duration(milliseconds: 500), //The animation time is 500 milliseconds pageBuilder: (BuildContext context, Animation animation, Animation secondaryAnimation) { return FadeTransition( //Using a fade in transition, opacity: animation, child: PageB(), //Route B ); }, ), );
We can see that pageBuilder has an animation parameter, which is provided by the fluent route manager. During route switching, pageBuilder will be recalled in each animation frame, so we can customize the transition animation through the animation object.
Whether MaterialPageRoute, CupertinoPageRoute, or PageRouteBuilder, they all inherit from the PageRoute class. In fact, PageRouteBuilder is just a wrapper of PageRoute. We can directly inherit the PageRoute class to implement custom routing. The above example can be implemented in the following ways:
1. Define a routing class FadeRoute
class FadeRoute extends PageRoute { FadeRoute( { this.barrierColor, this.barrierLabel, required this.builder, this.transitionDuration = const Duration(milliseconds: 300), this.opaque = true, this.barrierDismissible = false, this.maintainState = true, }); final WidgetBuilder builder; @override final Duration transitionDuration; @override final bool opaque; @override final bool barrierDismissible; @override final Color ? barrierColor; @override final String ? barrierLabel; @override final bool maintainState; @override Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) => builder(context); @override Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) { return FadeTransition( opacity: animation, child: builder(context), ); } }
2. Use FadeRoute
Navigator.push(context, FadeRoute(builder: (context) { return MyCustomAmniatonPageB(); }));
Although the above two methods can realize custom switching animation, PageRouteBuilder should be given priority in actual use, so there is no need to define a new routing class and it will be more convenient to use. However, sometimes PageRouteBuilder cannot meet the requirements. For example, when applying transition animation, we need to read some properties of the current route. At this time, we can only inherit PageRoute. For example, if we only want to apply animation when opening a new route and do not use animation when returning, Then we must judge whether the isActive attribute of the current route is true when building the transition animation. The code is as follows:
@override Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) { //The current route is activated to open a new route if(isActive) { return FadeTransition( opacity: animation, child: builder(context), ); }else{ //Yes, no transition animation is applied return Padding(padding: EdgeInsets.zero); } }
For detailed information about routing parameters, readers can refer to API documents by themselves,
PageRoute class - widgets library - Dart API
demo complete code: flutter_ Demo: fluent component test learning demo