32. User defined route switching animation of fluent

Posted by KendersPlace on Thu, 13 Jan 2022 02:05:30 +0100

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

Topics: iOS Android Flutter