flutter 路由管理

135 阅读3分钟

Navigator

Navigator是一个路由管理的组件,它提供了打开和退出的路由页方法。通过一个栈来管理活动路由集合。通常当前屏幕显示的页面就是栈顶的路由。

  1. Future push(BuildContext context, Route route)

将给定的路由入栈(即打开新的页面),返回值是一个Future对象,用以接收新路由出栈(即关闭)时的返回数据。

  1. Navigator.pop(BuildContext context,[ T? result ])

将栈顶路由出栈,result 为页面关闭时返回给上一个页面的数据。第二个参数是返回时路由携带的参数。

  1. Navigator.pushNamed(BuildContext context,routeName,arguments) 如果是导航到对应名称的 routes 里时,使用pushNamed()的方法。那么就需要对路由别名管理。如下代码,initialRoute 是初始化的路由,routes是对路由进行的管理。
MaterialApp(
  title: 'Named Routes Demo',
  initialRoute: '/',
  routes: {
    '/': (context) => const FirstScreen(),
    '/second': (context) => const SecondScreen(),
  },
)

routeName:是路由别名。arguments:是可选参数,即需要携带的参数。下面写个简单的路由跳转实例,以及怎么在widget中使用路由传参。

Navigator.pushNamed(
      context,
      ExtractArgumentsScreen.routeName,
      arguments: ScreenArguments(
        'Extract Arguments Screen',
        'This message is extracted in the build method.',
      ),
    );

获取路由中的参数,ModalRoute.of(context)!.settings.arguments,部分代码。

class ExtractArgumentsScreen extends StatelessWidget {
  const ExtractArgumentsScreen({super.key});

  static const routeName = '/extractArguments';

  @override
  Widget build(BuildContext context) {
  
    final args = ModalRoute.of(context)!.settings.arguments as ScreenArguments;

    return Scaffold(
      appBar: AppBar(
        title: Text(args.title),
      ),
      body: Center(
        child: Text(args.message),
      ),
    );
  }
}

注: 实例方法

Navigator类中第一个参数为context的静态方法都对应一个Navigator的实例方法。比如Navigator.push(BuildContext context, Route route)等价于Navigator.of(context).push(Route route)

注:上面Route类型的参数route,就是下面的MaterialPageRoute类。

MaterialPageRoute

MaterialPageRoute继承自PageRoute类,MaterialPageRoute 是 Material组件库提供的组件,它可以针对不同平台,实现与平台页面切换动画风格一致的路由切换动画:

 MaterialPageRoute({
    WidgetBuilder builder,
    RouteSettings settings, 
    bool maintainState = true, 
    bool fullscreenDialog = false, 
})
  1. WidgetBuilder builder, // 是一个WidgetBuilder类型的回调函数,它的作用是构建路由页面的具体内容,返回值是一个widget。我们通常要实现此回调,返回新路由的实例。
  2. RouteSettings settings, // 包含路由的配置信息,如路由名称、是否初始路由(首页)。
  3. bool maintainState = true, //默认情况下,当入栈一个新路由时,原来的路由仍然会被保存在内存中,如果想在路由没用的时候释放其所占用的所有资源,可以设置maintainState为 false
  4. bool fullscreenDialog = false, // 示新的路由页面是否是一个全屏的模态对话框,在 iOS 中,如果fullscreenDialogtrue,新页面将会从屏幕底部滑入

onGenerateRoute

onGenerateRoute是除了直接从组件里提取参数,你也可以通过 onGenerateRoute() 函数提取参数,然后把参数传递给组件。

onGenerateRoute() 函数会基于给定的 RouteSettings 来创建正确的路由。这有点路由拦截的意思了。下面这个一段代码的例子,onGenerateRoute是MaterialApp的一个参数,函数类型,回传settings,这个参数和在widget中去参数的settings一致。取出参数,然后返回一个widget,如果不符合判定返回null。

MaterialApp(

  onGenerateRoute: (settings) {

    if (settings.name == '/extractArguments') {

      final args = settings.arguments as ScreenArguments;

      return MaterialPageRoute(
        builder: (context) {
          return PassArgumentsScreen(
            title: args.title,
            message: args.message,
          );
        },
      );
    }
    assert(false, 'Need to implement ${settings.name}');
    return null;
  },
)

unknownRoute

unknownRoute也是MaterialApp的一个参数,对未知的路由进行处理,一般是整个404的页面。