美文网首页前端开发那些事儿
Flutter之路由管理(页面跳转)

Flutter之路由管理(页面跳转)

作者: yytester | 来源:发表于2020-12-14 11:20 被阅读0次

    路由:核心是 路由映射表.
    如:名字detail映射到 DetailPage页面等

    在Flutter中,路由管理主要有两个类:Route和Navigator.

    Route

    一个页面要想被路由统一管理,必须包装为一个Route

    Navigator

    管理所有的Route的Widget,通过一个Stack来进行管理.

    MaterialApp、CupertinoApp、WidgetsApp它们默认是有插入Navigator的,在需要的时候,只需要直接使用即可.
    Navigator.of(context)

    Navigator常用方法:

    // 路由跳转:传入一个路由对象
    Future<T> push<T extendsObject>(Route<T> route)
    
    // 路由跳转:传入一个名称(命名路由)
    Future<T> pushNamed<T extendsObject>(
      String routeName, {
        Object arguments,
      })
    
    // 路由返回:可以传入一个参数
    bool pop<T extendsObject>([ T result ])
    

    命名路由

    • 命名路由是将名字和路由的映射关系,在一个地方进行统一的管理
    • 有了命名路由,就可以通过Navigator.pushNamed()方法来跳转到新的页面

    命名路由的位置

    放在MaterialApp的 initialRoute 和 routes 中

    • initialRoute:设置应用程序从哪一个路由开始启动,设置了该属性,就不需要再设置home属性了

    • routes:定义名称和路由之间的映射关系,类型为 Map<String, WidgetBuilder>

    • onGenerateRoute: 通过pushNamed进行跳转,但是对应的name没有在routes中有映射关系,那么就会执行onGenerateRoute 钩子函数 . 另外, onGenerateRoute也可以作为页面跳转的权限控制.;

    • onUnknownRoute: 如果打开的一个路由名称是根本不存在的,这个时候可以跳转到一个统一的错误页面。

    打开命名路由时,如果指定的路由名在路由表中已注册,则会调用路由表中的builder函数来生成路由组件;如果路由表中没有注册,才会调用onGenerateRoute来生成路由。

    完整代码

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
              primarySwatch: Colors.blue, splashColor: Colors.transparent),
          initialRoute: "/",
          routes: {
            "/": (context) => MyHomePage(title: 'Flutter Demo Home Page'), //注册首页路由
            // "/home": (ctx) => HomePage(),
            "/detail": (ctx) => DetailPage()
          },
          onGenerateRoute: (settings) {  //路由钩子 .  手动创建对应的Route进行返回;
            if (settings.name == "/about") {   //settings.name: 跳转的路径名称
              return MaterialPageRoute(builder: (ctx) {
                return AboutPage(settings.arguments);  //settings.arguments:跳转时携带的参数
              });
            }
            return null;
          },
          onUnknownRoute: (settings) {
            return MaterialPageRoute(builder: (ctx) {
              return UnknownPage();
            });
          },
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      // final message = ModalRoute.of(context).settings.arguments;
    
      var _message = '';
    
      _onPushTop(BuildContext context) {
        final future = Navigator.of(context)
            .pushNamed('/detail', arguments: "a home message of naned route"); //主动跳转时arguments传递参数
    
        // 2.获取结果
        future.then((res) {
          setState(() {
            _message = res;
          });
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(
                  '显示结果: ' + _message,
                ),
                FlatButton(
                  child: Text("跳转下一页", style: TextStyle(color: Colors.black)),
                  onPressed: () => _onPushTop(context),
                ),
                RaisedButton(
                  child: Text("打开关于页"),
                  onPressed: () {
                    Navigator.of(context).pushNamed(AboutPage.routeName,
                        arguments: "a home message");
                  },
                ),
                RaisedButton(
                  child: Text("打开未知页面"),
                  onPressed: () {
                    Navigator.of(context).pushNamed("/abc");
                  },
                ),
              ],
            ),
          ),
        );
      }
    }
    
    class DetailPage extends StatelessWidget {
      // 按钮点击执行的代码
      _onBackTap(BuildContext context) {
        Navigator.of(context).pop("a detail message");
      }
    
      @override
      Widget build(BuildContext context) {
        
        //接收上级页面传过来的参数
        final message = ModalRoute.of(context).settings.arguments;
    
        return new Scaffold(
          appBar: new AppBar(
            title: Text('这是第二页'),
            leading: IconButton(
              icon: Icon(Icons.arrow_back),
              onPressed: () {
                Navigator.of(context).pop("a back detail message"); //pop跳转时直接放入参数
              },
            ),
          ),
          body: Center(
            child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text(
                    '首页带来的内容: ' + message,
                  ),
    
                  // child:
                  RaisedButton(
                    child: Text("返回首页"),
                    onPressed: () => _onBackTap(context),
                  ),
                ]),
          ),
        );
      }
    }
    
    class AboutPage extends StatelessWidget {
      static const String routeName = "/about";
      final String message;
    
      AboutPage(this.message);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("关于页面"),
          ),
          body: Center(
            child: Text(
              message,
              style: TextStyle(fontSize: 30, color: Colors.red),
            ),
          ),
        );
      }
    }
    
    class UnknownPage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("错误页面"),
          ),
          body: Container(
            child: Center(
              child: Text("页面跳转错误"),
            ),
          ),
        );
      }
    }
    

    参考文章

    Flutter 写的app, 需要源码可以私信~~


    最好的笔记软件

    https://www.wolai.com/signup?invitation=6Z8Z3BP

    相关文章

      网友评论

        本文标题:Flutter之路由管理(页面跳转)

        本文链接:https://www.haomeiwen.com/subject/qfhvgktx.html