Flutter 自身是提供了 Navigator
widget 来实现应用的路由功能。但使用一些路由插件,可以帮助我们更方便快捷的实现 Flutter 应用页面间的跳转和传值等功能。
这篇笔记我们主要来学习一下 fluro 这个插件。
1. 项目引入 fluro
Flutter 应用中要使用任何第三方插件,都需要先在项目中进行引入。
打开项目根目录中的 pubspec.yaml
文件,在 dependencies
属性下面添加 fluro 的配置代码:
dependencies:
fluro: ^1.6.3
参考代码截图如下:
说明:1.6.3 是当前(2020.04.13)fluro 的最新版本号,大家以后在使用时,建议先去 官网看看最新的版本号是多少,配置的时候就改成最新版本号即可。
2. fluro 的基本使用
fluro 最基本的功能就是“跳转页面”,其他的“传值”、“返回”等功能对于我们菜鸡来说都是高级操作了,所以先不谈。我们先来学基操!
2.1 建立路由文件
一般情况下,我们都会在项目的 lib 目录中创建一个的新的文件夹(例如:lib/routers
),专门用来存放与路由相关的配置代码。
2.2 路由配置
创建一个 lib/routers/routes.dart
文件用来进行路由的相关配置:
import 'package:flutter/material.dart';
// 引入 fluro
import 'package:fluro/fluro.dart';
// 引入路由要跳转的页面文件
import 'package:flutter_fluro_demo/home_page.dart';
import 'package:flutter_fluro_demo/login_page.dart';
class Routes {
// 各个页面的路径字符串
static String home = '/home';
static String login = '/login';
// 创建一个 configureRoutes 方法,用于路由配置
static void configureRoutes(Router router) {
// 配置 home 首页路由
router.define(home, handler: Handler(
handlerFunc: (BuildContext context, Map> params) {
return HomePage();
},
),
);
// 配置 login 登录页路由
router.define(login, handler: Handler(
handlerFunc: (BuildContext context, Map> params) {
return LoginPage();
}
),
);
}
}
在这个配置文件里,我们以“首页”和“登录页”为例,做了一个最基础的路由配置。
2.3 路由静态化处理
为了方便我们后面在各个页面中使用路由,我建议(官方也建议)先对路由做一个静态化处理。
在 lib/routers
中再创建一个 application.dart
文件,添加以下代码:
import 'package:fluro/fluro.dart';
class Application {
static Router router;
}
在这段代码中,我们创建了一个 Application 对象,并设置了一个静态属性 router。
在下一步全局注入路由的时候,我们会把调用 Router()
方法得到的路由对象保存在 Application.router
属性中。这样,在后续各个页面中使用路由时,就可以直接通过 Application.router
来拿到路由对象,而不需要反复调用 Router()
方法了。
2.4 全局注入路由
各项配置完成之后,接下来就需要在项目入口文件 main.dart
中注入路由来使我们的路由生效。
import 'package:flutter/material.dart';
import 'package:fluro/fluro.dart';
import 'package:flutter_fluro_demo/routers/routes.dart'; // 路由配置文件
import 'package:flutter_fluro_demo/routers/application.dart'; // 路由静态化文件
void main() {
final router = Router(); // 获取路由对象
Routes.configureRoutes(router); // 调用路由配置方法
Application.router = router; // 将路由对象静态化
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
onGenerateRoute: Application.router.generator, // 将路由配置到 MaterialApp 中
// ...
);
}
}
2.5 路由跳转
fluro 中最简单的跳转方式就是通过 navigateTo()
方法来实现:
import 'package:flutter_fluro_demo/routers/application.dart';
// ...
Application.router.navigateTo(context, '/home');
参考代码截图如下:
3. fluro 的进阶使用
路由的基本使用学会了之后,接下来我们就需要增加一丢丢的难度了。
3.1 拆分路由配置文件
在前面的路由基础用法里,我们将所有关于路由的配置都放在了 routes.dart
文件中,当我们项目的页面逐渐增多时,就会导致这个文件变得越来越大,代码越来越多,后期维护起来也会越来越不方便。
所以,我们要对 routes.dart
文件中的代码进行拆分。
routes.dart
原本的代码如下:
从图中代码可以看到,路由操作的大部分代码都集中在了 handler
属性中,因此,我们就把每一个 handler
属性的属性值都提取出去。
在 lib/routers
中再创建一个文件:route_handlers.dart
,将拆分出来的代码放进去:
import 'package:flutter/material.dart';
import 'package:fluro/fluro.dart';
import 'package:flutter_fluro_demo/home_page.dart';
import 'package:flutter_fluro_demo/login_page.dart';
Handler homeHandler = Handler(
handlerFunc: (BuildContext context, Map> params) {
return HomePage();
},
);
Handler loginHandler = Handler(
handlerFunc: (BuildContext context, Map> params) {
return LoginPage();
},
);
这样拆分后,我们原本的 routes.dart
文件就变得很干净了。
import 'package:fluro/fluro.dart';
import './route_handlers.dart';
class Routes {
static String home = '/home';
static String login = '/login';
static void configureRoutes(Router router) {
router.define(home, handler: homeHandler);
router.define(login, handler: loginHandler);
}
}
3.2 路由传参
虽然我们把路由传参划分到了进阶用法里,但是实际上我们应该都清楚,任何一个 App 里,路由传参功能都是必不可少的。更何况,fluro 的路由传参其实 so easy~
路由传参其实简单理解为一个点外卖的过程。例如我们要将 home 页面的数据传递 detail 页面,那么 home 页面就是商家,detial 页面就是整天宅在家里扣 jio 的你,而 fluro,就是我们的外卖骑手。
理解了传参的流程之后,接下来我们就可以开始搬砖了。
第一步:在 detial 页面配置要接收的参数
detail 页面中的代码如下:
import 'package:flutter/material.dart';
class DetailPage extends StatelessWidget {
DetailPage({this.detailId});
final String detailId;
//...
}
这里我们定义了一个 detailId
,用来接收后面 home 传递过来的参数。
我的案例代码截图如下:
第二步:在 home 页面设置要传递的参数
home 页面的路由跳转和传参代码如下:
RaisedButton(
child: Text('去详情页'),
onPressed: () {
Application.router.navigateTo(context, '/detail/001');
},
),
/detail/001
中的 /detail
就是我们要去到的 detail 页面的路径,001
就是我们要传递给 detail 页面的参数。
第三步:在路由配置文件中对 detail 路由进行配置
打开 lib/routers/routes.dart
文件,对 detail 的路由进行如下配置:
class Routes {
// ...
static String detail = '/detail/:id';
static void configureRoutes(Router router) {
// ...
router.define(detail, handler: detailHandler);
}
}
参考代码截图如下:
(detailHandler
报错是因为我们还没创建这个变量,下一步创建好就不会报错了。)
/detail/:id
中的 id
是我们自己定义的一个参数名,是对 home 页面传递的参数进行命名。
接下来,再打开 lib/routers/routes_handlers.dart
文件,配置 detail 的 handler 方法。
import 'package:flutter_fluro_demo/detail_page.dart';
// ...
Handler detailHandler = Handler(
handlerFunc: (BuildContext context, Map> params) {
String id = params['id'].first; // 通过 params 获取到路由中传递的参数
return DetailPage(detailId: id);
},
);
到此,我们 home 页面,通过路由往 detail 页面的传参就已经完成了。
3.3 返回页面
在 Flutter 中,跳转后的页面左上角会自带一个返回箭头,但是有的时候,我们也需要点击界面其他地方来实现页面的返回,又或者,我们想返回到一个指定的界面。
3.3.1 返回到上一页面
页面返回的代码很简单:
RaisedButton(
child: Text('返回上一页'),
onPressed: () {
// flutter
Navigator.pop(context);
// fluro
// Application.router.pop(context);
},
)
从上面代码可以看出,实现“返回上一页面”功能的方式两种:一种是 flutter 自带的 Navigator
widget 提供的 pop 方法;另一种是 fluro 中提供的 pop 方法。
这里我们列出 flutter 原生的返回方式,是因为 flutter 原生的方式更简洁一些,所以路由的返回功能我们更多会选择直接用 Navigator
的方法返回。
3.3.2 返回到指定页面
fluro 中并没有提供专门的“返回到指定页面”的方法(我有看 fluro 的源码,确实没有找到,如果这里说法有误请大家评论里告诉我)。所以如果我们想要实现“返回到指定页面”的效果,可以直接用 navigateTo
页面跳转方法实现。
具体代码可以参考前面「2.5 路由跳转」的示例代码。
3.4 管理历史记录
默认情况下,每一次的路由跳转,都会有一个新的路由记录注册到路由表中。
fluro 中的 navigateTo()
方法可以设置第三个参数来管理路由历史记录。
3.4.1 替换历史记录
替换历史记录是指用“跳转后的新页面”记录替换掉“当前页面”记录。将 navigateTo()
方法的第三个参数设置为 replace: true
即可。
child: RaisedButton(
child: Text('去详情页'),
onPressed: () {
Application.router.navigateTo(context, '/detail/001', replace: true);
},
),
参考代码截图如下:
当我们从“登录页”跳转到“首页”,再从“首页”跳转到“详情页”,然后点击“详情页”左上角的返回按钮,可以发现,直接返回到了“登录页”。因为我们的历史记录里面已经没有保留“首页”的记录了。
3.4.2 清空历史记录
除了替换一条历史记录外,navigateTo()
方法还可以将第三个参数设置为 clearStack: true
来实现清空历史记录的效果。
child: RaisedButton(
child: Text('去详情页'),
onPressed: () {
Application.router.navigateTo(context, '/detail/001', clearStack: true);
},
),
4. 最后
fluro 的用法大概就是这些了,如果还有没写到的知识点,大家可以在评论里告诉我,我再补充。