代码之家  ›  专栏  ›  技术社区  ›  Chris

像iOS 13模式全屏一样的Flutter过渡

  •  0
  • Chris  · 技术社区  · 5 年前

    我想有一个iOS模式转换,新屏幕从底部动画化,旧屏幕被推到后面。我发现这个非常有希望的方案:

    modal_bottom_sheet

    这是我用来显示模态的函数:

    showCupertinoModalBottomSheet(
                      expand: true,
                      context: context,
                      builder: (context) => Container(
                        color: AppColors.blue,
                      ),
                    );
    

    然而,这并不能100%正确地工作,因为后面的视图没有被推到后面。

    我在这里错过了什么?如果有什么不清楚的地方,请告诉我!

    以下是我的更多代码:

    这是我的整个页面,我想从这里进行过渡:

        class _MonthPageState extends State<MonthPage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: AppColors.secondary,
          body: SafeArea(
            child: Stack(
              children: [
                ...
                Positioned(
                  bottom: 10,
                  right: 20,
                  child: Hero(
                    tag: widget.month.name + 'icon',
                    child: AddButton(
                      onTapped: () {
                        showCupertinoModalBottomSheet(
                          expand: true,
                          context: context,
                          builder: (context) => Container(
                            color: AppColors.blue,
                          ),
                        );
                      },
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
      }
    

    这是我的路由器:

        class AppRouter {
      static Route<dynamic> generateRoute(RouteSettings settings) {
        switch (settings.name) {
          case '/':
            return MaterialWithModalsPageRoute(
              builder: (context) => HomePage(),
            );
          case '/month':
            final Month month = settings.arguments as Month;
            return _buildTransitionToMonthPage(month);
          default:
            return MaterialPageRoute(
              builder: (_) => Scaffold(
                body: Center(
                  child: Text('No route defined for ${settings.name}'),
                ),
              ),
            );
        }
      }
    
      static PageRouteBuilder _buildTransitionToMonthPage(Month month) {
        return PageRouteBuilder(
          transitionDuration: Duration(milliseconds: 450),
          reverseTransitionDuration: Duration(milliseconds: 450),
          pageBuilder: (BuildContext context, Animation<double> animation,
              Animation<double> secondaryAnimation) {
            return MonthPage(
              month: month,
            );
          },
          transitionsBuilder: (BuildContext context, Animation<double> animation,
              Animation<double> secondaryAnimation, Widget child) {
            return FadeTransition(opacity: animation, child: child);
          },
        );
      }
    }
    
    0 回复  |  直到 5 年前
        1
  •  4
  •   Mobina Andres Romero    5 年前

    为了获得推后动画,您需要使用 CupertinoScaffold 与并列 CupertinoPageScaffold ,例如。

      @override
      Widget build(BuildContext context) {
        return CupertinoScaffold(
          transitionBackgroundColor: Colors.white,
          body: Builder(
            builder: (context) => CupertinoPageScaffold(
              backgroundColor: Colors.white,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Center(
                    child: ElevatedButton(
                        child: Text('show modal'),
                        onPressed: () =>
                            CupertinoScaffold.showCupertinoModalBottomSheet(
                              expand: true,
                              context: context,
                              backgroundColor: Colors.white,
                              builder: (context) => Container(
                                  color: Colors.white,
                                  child: Center(
                                    child: ElevatedButton(
                                      onPressed: () => Navigator.of(context)
                                          .popUntil((route) =>
                                              route.settings.name == '/'),
                                      child: Text('return home'),
                                    ),
                                  )),
                            )),
                  ),
                ],
              ),
            ),
          ),
        );
      }
    
    推荐文章