入门flutter第五篇,路由(下)进阶

121 阅读3分钟

这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战

一、flutter路由

路由嘛,就是一个名字指向一个页面,确定了名字之后呢,在必要的检查之后就可以跳转到对应的页面了,是不是很好理解呀。

flutter开发app和uni-app所不同的是,uni-app的手感还是像在开发网页,通过路由传递参数。并不是说这样不好,只是和flutter传递参数的方式还是有所区别的。

当然不要担心差异太大,本质上都是携带参数,只是flutter在开发时看起来不像是通过路由携带参数。

并且也看不到flutter的路由。

搞一波

// lib/main.dart
import 'package:flutter/material.dart';
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp( // 路由在这里设置,
      routes: {
        "/": (context) => LoginPage(),
        "menu": (context) => MenuPage(), // 未注册跳转,通过路由拦截返回
      }
    );
  }
}

// navigator.dart
import 'package:flutter/material.dart';

class MenuPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    dynamic arg = ModalRoute.of(context)?.settings.arguments;

    return Scaffold(
      appBar: AppBar(
        title: Text(arg.toString()),
        centerTitle: true,
      ),
      body: ElevatedButton(
        onPressed: () {
          // 返回值可以是任意类型,包括不限于是对象
          Navigator.of(context).pop("返回");
        },
        child: Text('返回'),
      ),
    );
  }
}

class LoginPage extends StatelessWidget {
  const LoginPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("登录"),
        centerTitle: true,
      ),
      body: ElevatedButton(
        child: Text("登录"),
      ),
    );
  }
}

在上面代码的main文件中的主函数中,可以看到配置好的路由,默认的是以配置的第一条路由作为初始界面,也可以自定义初识界面。

  routes: {
    // ... 路由
  },
  initialRoute: 'menu',

此外就是上一篇中提到的路由拦截了,在目前的配置下,只完成路由的配置,但是并不能在路由跳转的中间添加一些自定义的函数,所以再次修改。

    routes: {
      "/": (context) => loginPage(),
    },
    onGenerateRoute: (RouteSettings arg){
      switch(s.name){
        case "menu":
            return MaterialPageRoute(){
              builder: (context){
                return MenuPage()
              },
              settings: arg); // 将传递的参数继续传递给下一个页面。
            }
            break;
      }
    }

如上,将需要拦截的页面通过onGenerateRoute属性检测并返回,如此便可以做到在路由跳转的间隙中做一个检测了。

三、路由传参

路由传参的方法在前面提过,这里在简单提一下,免得各位观众老爷还要回头去看。

// MenuPage 类
body: ElevatedButton(
    onPressed: () {
      // 返回值可以是任意类型,包括不限于是对象
      Navigator.of(context).pop("返回");
    },
    child: Text('返回'),
),

// LoginPage 类
body: ElevatedButton(
    // 异步操作时,添加async关键字
    onPressed: () {
      // 跳转到命名路由
      Navigator.of(context)
          // .popAndPushNamed("menu", arguments: "菜单") // 类似于replace,关闭当前页?
          .pushNamed("menu", arguments: "菜单") // 类似于replace,关闭当前页?
          .then((value) => print(value));
    },
    child: Text("登录"),
),

上述代码,MenuPage中是在返回时,带参数返回的写法,可以反馈给上个页面信息。

LoginPagepushName的第二个参数带参跳转,则可以传递一些数据给进入的页面。

举个例子,有这样一个活动,点击按钮前往阅读一篇文章,阅读10秒钟可返回当前页领取道具。

从当前页前往文章页时携带一个进入时间的时间戳,从文章页返回再携带一个退出的时间戳,以此计算比用定时器更节省资源不是嘛?

啦啦啦,举个例子,实际应用看需求的哦。