Flutter(八):Flutter路由管理(Router)

一、术语

路由(route)

  • 在 Flutter 中,屏 (screen) 和 页面 (page) 都叫做 路由 (route)。
  • 在 Android 开发中,Activity 相当于“路由”,在 iOS 开发中,ViewController 相当于“路由”。在 Flutter 中,“路由”也是一个 widget。

导航(Navigator):

  • Navigator是一个路由管理的组件,它提供了打开和退出路由页方法。Navigator官方链接
  • Navigator常用的路由管理方法包括pushpop

二、路由管理

1、Navigator示例代码

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        routes: {
          '/': (context) => const HomePage(),
          '/second': (context) => const SecondScreen(),
        });
  }
}

/// 第一个页面
class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home'),
      ),
      body: Center(
        child: Column(
          children: [
            ElevatedButton(
              onPressed: () {
                Navigator.push(context, MaterialPageRoute(
                    builder: (context) => const SecondScreen(),
                  ),
                );
              },
              child: const Text('使用Navigator+构造器跳转'),
            ),
            ElevatedButton(
              onPressed: () {
                Navigator.pushNamed(context, '/second');
              },
              child: const Text('使用Navigator+命名路由跳转'),
            ),
          ],
        ),
      ),
    );
  }
}

/// 第二个页面
class SecondScreen extends StatelessWidget {
  const SecondScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Second Screen'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: const Text('Go back!'),
        ),
      ),
    );
  }
}

2、路由定义(命名路由)

在App中定义router:

routes: {
          '/': (context) => const HomePage(),
          '/second': (context) => const SecondScreen(),
        }

3、Navigator方法介绍

1.Navigator.push

  • push(BuildContext context, Route route)

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

  • pushNamed(BuildContext context, String routeName, {Object? arguments,})

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

2.Navigor.pop

  • pop(BuildContext context, [ T? result ])

将栈顶路由出栈,result为页面关闭时返回给上一个页面的数据

3.其他

Navigator还有很多其他方法,如Navigator.replaceNavigator.popUntil等,具体参考Navigator官方链接

3、路由传值

示例代码

定义传值Model

class DetailInfo {
  final String title;
  final String message;
  final String? other;

  DetailInfo(this.title, this.message,{this.other});
}

使用pushNamed传递数据

Navigator.pushNamed(context, '/second', arguments: DetailInfo('详情页','返回'));

获取数据

使用MaterialPageRoute中的ModalRoute来获取路由参数,注意要避空

final detail = ModalRoute.of(context)?.settings.arguments as DetailInfo?;

完整代码:

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

  @override
  Widget build(BuildContext context) {

    final detail = ModalRoute.of(context)?.settings.arguments as DetailInfo?;

    return Scaffold(
      appBar: AppBar(
        title: Text(detail?.title ?? ''),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text(detail?.message ?? ''),
        ),
      ),
    );
  }
}

4、其他

1.返回到指定页面

Navigator.popUntil(context, ModalRoute.withName('/'));

2.跳转指定页面,并销毁当前页

Navigator.pushReplacementNamed(context, '/third');

3.推出当前页,然后跳转指定页

会有一个推出的动画效果

Navigator.popAndPushNamed(context, '/third');

热门相关:帝少的专属:小甜心,太缠人