Flutter 第四课---路由管理

480 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情

Flutter系列文章列表

  1. 2022年了,你还不会flutter!!!
  2. Flutter 第一课---flutter特点及组件开发
  3. Flutter 第二课---组件生命周期和App生命周期
  4. Flutter 第三课---状态管理之Provide

什么是路由管理

路由管理即是管理页面之间如何跳转。它会维护一个路由栈,路由入栈(push)操作对应打开一个新页面,路由出栈(pop)操作对应页面关闭操作。这跟Vue中的Router概念意义是相同的。在不调用后端接口的基础上,进行页面的切换。以此来减低页面白屏(痛点)问题。

路由管路方式

基本路由和命名路由。

Navigator

Navigator是一个路由管理的widget,它通过一个栈来管理一个路由widget集合。通常当前屏幕显示的页面就是栈顶的路由。

基本路由

基本路由需要自己手动创建页面实例,通过 Navigator.push 完成页面跳转。Navigator.push(BuildContext context, Route route)等价于Navigator.of(context).push(Route route)

  1. 不带参数
Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => const SettingPage()),
);
  1. 带参数
  • 在A页面的路由跳转中传递值即可
Navigator.push(
  context,
  MaterialPageRoute(builder: (context) {
    return const NewRoute(myName: 'my name is super start',);
  }),
);
  • 在子页面接收传递参数
class NewRoute extends StatefulWidget {
  const NewRoute({Key? key,required this.myName}) : super(key: key);
  final String myName;

  @override
  State<NewRoute> createState() => _NewRouteState();
}
  • 使用路由传递参数
class _NewRouteState extends State<NewRoute> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("New route"),
      ),
      body: Center(
        child: Text('基本路由跳转页面-传值内容:${widget.myName}'),
      ),
    );
  }
}

若子组件是无状态组件(StatelessWidget),则直接使用myName调用,若为有状态组件(StatefulWidget),则需要使用widget.myName调用

命名路由

而命名路由需要提前注册路由表及映射方法,通过 Navigator.pushNamed 传入标识符实现页面跳转。

  • 注册路由表
import 'package:flutter/material.dart';
import '../page/HomePage.dart';
import '../page/SettingPage.dart';
import '../page/CollectPage.dart';
import '../page/FancyTextPage.dart';
import '../components/ChooseItem.dart';

final routes = {
  '/': (context) => const HomePage(),
  '/setting': (context) => const SettingPage(),
  '/collect': (context) => const CollectPage(),
  '/fancytext': (context) => const FancyTextPage(),
  '/choice': (context, {arguments}) => ChooseItem(arguments: arguments),
};

//固定写法
Route<dynamic> onGenerateRoute(RouteSettings settings) {
  return MaterialPageRoute(builder: (context) {
    String? name = settings.name;
    Function? pageContentBuilder = routes[name] as Function;
    //如果存在参数
    if (settings.arguments != null) {
      var arguments = settings.arguments;
      return pageContentBuilder(context, arguments: arguments);
    }
    //参数不存在时候
    else {
      return pageContentBuilder(context);
    }
  });
}
  • 之后然后再在全局变量里面进行引入
import './route/index.dart';

image.png

这样组件与路由之间的映射关系就完成了。

  1. 不带参数
Navigator.pushNamed(context, "one_page");
  1. 带参数
  • 在打开路由时传递参数
Navigator.of(context).pushNamed("one_page", arguments: "命名路由传的的参数");
  • 在路由页通过RouteSetting对象获取路由参数
Widget build(BuildContext context) {
    var args = ModalRoute.of(context)!.settings.arguments;
    print(args);
}

命名路由的优点

在实际开发中,会犹豫到底使用哪种路由管理方式。建议最好统一使用命名路由的管理方式,这将会带来如下好处:

  1. 语义化更明确。
  2. 代码更好维护。

结束语

关于flutter路由管理的学习到这里就结束了。下期我们来说说flutter资源管理。如果你刚好正在学习flutter,可以关注我,请相信会给你不一样的收获。如果你是flutter大佬,欢迎指导!