使用onGenerateRoute在屏幕之间进行有条件的退出转换

问题描述

我正在通过onGenerateRoute设置路线和过渡动画,效果很好,只是我希望根据条件(例如在选定的路径上)设置不同的过渡动画:

import 'package:Flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      initialRoute: '/',onGenerateRoute: (RouteSettings settings) {
        if (settings.name == '/') {
          return PageRouteBuilder<dynamic>(
            pageBuilder: (BuildContext context,Animation<double> animation,Animation<double> secondaryAnimation) =>
                Page1(),transitionsBuilder: (
              BuildContext context,Animation<double> secondaryAnimation,Widget child,) {
              return SlideTransition(
                position: Tween<Offset>(
                  begin: Offset.zero,end: const Offset(-1.0,0.0),).animate(secondaryAnimation),// Here I want to have differents transitions
                child: child,);
            },);
        } else if (settings.name == '/second') {
          return PageRouteBuilder<dynamic>(
            pageBuilder: (BuildContext context,Animation<double> secondaryAnimation) =>
                Page2(),) {
              return SlideTransition(
                  position: Tween<Offset>(
                          begin: const Offset(1.0,end: Offset.zero)
                      .animate(animation),child: SlideTransition(
                    position: Tween<Offset>(
                      begin: Offset.zero,end: const Offset(0.0,1.0),child: child,));
            },);
        } else if (settings.name == '/third') {
          return PageRouteBuilder<dynamic>(
            pageBuilder: (BuildContext context,Animation<double> secondaryAnimation) =>
                Page3(),) {
              return SlideTransition(
                  position: Tween<Offset>(
                          begin: const Offset(0.0,);
        } else {
          return null;
        }
      },);
  }
}

class Page1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Page 1"),backgroundColor: Colors.blue),backgroundColor: Colors.blue,body: Column(
        children: [
          Center(
            child: RaisedButton(
              onpressed: () => Navigator.pushNamed(context,'/second'),child: Text("Go to Page 2 with exit transition slide left"),),Center(
            child: RaisedButton(
              onpressed: () => Navigator.pushNamed(context,'/third'),child: Text("Go to Page 3 with transition slide top"),],);
  }
}

class Page2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Page 2"),backgroundColor: Colors.green),backgroundColor: Colors.green,body: Center(
          child: RaisedButton(
              onpressed: () => Navigator.of(context).pop(),child: Text("Go back to page 1"))),);
  }
}

class Page3 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Page 3"),backgroundColor: Colors.yellow),backgroundColor: Colors.yellow,);
  }
}

See codePen here

由于在显示屏幕之前设置了退出过渡动画(通过secondaryAnimation,所以我无法根据单击的按钮来动态更改动画。我该如何实现?

解决方法

   (RouteSettings settings) {
      final transition = settings.arguments as String;
      if (settings.name == '/') {
      return PageRouteBuilder<dynamic>(
        pageBuilder: (BuildContext context,Animation<double> animation,Animation<double> secondaryAnimation) =>
            Page1(),transitionsBuilder: (
          BuildContext context,Animation<double> secondaryAnimation,Widget child,) {
           switch (transition) {
             case 'firstTransition':
               secondaryAnimation = //first animation 
             break;
             case 'secondTransition':
               secondaryAnimation = //second animation
             break;
           }

          return SlideTransition(
            position: Tween<Offset>(
              begin: Offset.zero,end: const Offset(-1.0,0.0),).animate(secondaryAnimation),// Here I want to have differents transitions
            child: child,);
        },);