使用WidgetsApp的应用程序导航示例

11

我正在尝试声明我的应用程序导航。由于我没有使用MaterialApp包装器或样式,所以我所有的导入都来自package:flutter/widgets.dart

根据文档,要正确使用导航,我正在做以下操作:

import "package:flutter/widgets.dart";
import "package:myapp/routes/home.dart";

void main() {
  runApp(
    new WidgetsApp(/* stuck here */);
  )
}

我卡在这一步了,我尝试遵循Navigator文档和IDE中的代码注释,但我无法弄清楚如何使用WidgetsApponGenerateRoute属性,也找不到完整的在线示例,因此提出问题。

类似于new MaterialApp(),我如何在new WidgetsApp()中定义我的主页路径和其余路由?

作为对此的后续问题,我能否在new WidgetsApp()内部以某种方式使用通配符路由,例如/onboarding/**/dashboard/**,以便进入具有用于检查路由并显示页面的switch语句的布局?

1个回答

15

您可以使用onGenerateRoute属性为小部件应用程序生成路由。

这是同样功能的非常简单的实现:

import 'package:flutter/widgets.dart';

void main() => runApp(new MyWidgetsApp());

class MyWidgetsApp extends StatelessWidget {

  Route generate(RouteSettings settings){
    Route page;
    switch(settings.name){
      case "/":
        page =  new PageRouteBuilder(
            pageBuilder: (BuildContext context,Animation<double> animation,
                Animation<double> secondaryAnimation){
              return new Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  const Text("Home Page",textDirection: TextDirection.ltr,),
                  const Padding(padding: const EdgeInsets.all(10.0)),
                  new GestureDetector(
                    onTap: () => Navigator.of(context).pushNamed("/first"),
                    child: new Container(
                      padding: const EdgeInsets.all(10.0),
                      color:Colors.blue,
                      child: const Text("Go to First Page"),
                    ),
                  ),
                  const Padding(padding: const EdgeInsets.all(10.0)),
                  new GestureDetector(
                    onTap: () => Navigator.of(context).pushNamed("/abcd"),
                    child: new Container(
                      padding: const EdgeInsets.all(10.0),
                      color:Colors.blue,
                      child: const Text("Unkown Route"),
                    ),
                  )
                ],
              );
            },
            transitionsBuilder: (_, Animation<double> animation, Animation<double> second, Widget child) {
              return new FadeTransition(
                opacity: animation,
                child: new FadeTransition(
                  opacity: new Tween<double>(begin: 1.0, end: 0.0).animate(second),
                  child: child,
                ),
              );
            }
        );
        break;
      case "/first":
        page =  new PageRouteBuilder(
            pageBuilder: (BuildContext context,Animation<double> animation,
                Animation<double> secondaryAnimation){
              return new Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    const Text("First Page",textDirection: TextDirection.ltr,),
                    const Padding(padding: const EdgeInsets.all(10.0)),
                    new GestureDetector(
                      onTap: () => Navigator.of(context).pop(),
                      child: new Container(
                        padding: const EdgeInsets.all(10.0),
                        color:Colors.blue,
                        child: const Text("Back"),
                      ),
                    )
                  ]
              );
            },
            transitionsBuilder: (_, Animation<double> animation, Animation<double> second, Widget child) {
              return new FadeTransition(
                opacity: animation,
                child: new FadeTransition(
                  opacity: new Tween<double>(begin: 1.0, end: 0.0).animate(second),
                  child: child,
                ),
              );
            }
        );
        break;
    }
    return page;
  }

  Route unKnownRoute(RouteSettings settings){
    return new PageRouteBuilder(
        pageBuilder: (BuildContext context,Animation<double> animation,
            Animation<double> secondaryAnimation){
          return new Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                const Text("First Page",textDirection: TextDirection.ltr,),
                const Padding(padding: const EdgeInsets.all(10.0)),
                new GestureDetector(
                  onTap: () => Navigator.of(context).pop(),
                  child: new Container(
                    padding: const EdgeInsets.all(10.0),
                    color:Colors.blue,
                    child: const Text("Back"),
                  ),
                )
              ]
          );
        }
    );
  }

  @override
  Widget build(BuildContext context) {
    return new WidgetsApp(
        onGenerateRoute: generate,
        onUnknownRoute: unKnownRoute,
        textStyle: const TextStyle(),
        initialRoute: "/",
        color: Colors.red
    );
  }
}

希望这能帮到你!


已经成功实现了您的版本,但是在解决如何使路线替换时出现问题。我遵循了Navigator api文档并使得旋转和淡入淡出过渡效果工作 (https://docs.flutter.io/flutter/widgets/Navigator-class.html)。我现在看到的问题是,在新路线动画进入时,旧路线仍然可见,直到新路线结束。理想情况下,我希望先将旧路线淡出旋转,然后再淡入新路线。 - Ilja
我刚刚更新了我的答案,将transitionsBuilder实现到PageRouteBuilder中。希望这就是你想要实现的效果。之前的路由会淡出,然后新的路由出现,反之亦然。希望这有所帮助! - Hemanth Raj
没错,它起到了作用,我缺少Tween,需要阅读有关动画文档的内容感谢您。如果您有时间进行后续操作:现在它们交叉淡入淡出,是否可以在开始“第二个”动画之前等待淡出完成(因此等待animation完成)? - Ilja
类似这样的东西 - Hemanth Raj
1
`class MyTween extends Tween<double>{ double begin; double end; MyTween({this.begin, this.end}):super(begin:begin,end:end); @override double lerp(double t){ final double val = begin + (end - begin) * t; return val<0.5?0.0:2*(val - 0.5); } }` - Hemanth Raj
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接