Flutter路由参数1 - 路由管理

1 基础知识

在了解Flutter的路由管理功能前,首先需要几个基础类有一定熟悉,以下简单介绍路由相关几个类的功能。

功能
Navigator 导航器,管理路由的Widget
Route及子类 用于Navigator管理的页面
RouteSettings及子类 保存页面配置信息,如name,arguments等

2 路由管理Navigator.push

管理Flutter路由分为两种方式:

  • 直接路由
  • 命名路由
路由方式 实现方式
直接路由 Navigator.push调用,使用Route进行路由
命名路由 Navigator.pushNamed调用,使用routeName进行路由

2.1 直接路由

2.1.1 源码

  @optionalTypeArgs
  static Future<T?> push<T extends Object?>(BuildContext context, Route<T> route) {
    return Navigator.of(context).push(route);
  }

2.1.2 使用演示

从TestHomePage页面路由到TestRouterPage。

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

  @override
  Widget build(BuildContext context) {
    ScreenUtil.init(context, designSize: const Size(375, 667));
    return Scaffold(
      body: GestureDetector(
        child: Center(
          child: Container(
            alignment: Alignment.center,
            decoration: BoxDecoration(border: Border.all(width: 1, color: Colors.red)),
            child: const Text("This is a home page. This is a home page. This is a home page.",
                textAlign: TextAlign.center, style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500, color: Colors.red)),
          ),
        ),
        onTap: () {
          Navigator.push(context, MaterialPageRoute(builder: (context) {
            return const TestRouterPage();
          }));
          // Navigator.pushNamed(context, TestRouterPage.routeName);
        },
      ),
    );
  }
}
class TestRouterPage extends StatelessWidget {
  const TestRouterPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          alignment: Alignment.center,
          decoration: BoxDecoration(border: Border.all(width: 1, color: Colors.blue)),
          child: const Text("This is a router page. ",
              textAlign: TextAlign.center, style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500, color: Colors.blue)),
        ),
      ),
    );
  }
}

2.2 命名路由

2.2.1 源码

  @optionalTypeArgs
  static Future<T?> pushNamed<T extends Object?>(
    BuildContext context,
    String routeName, {
    Object? arguments,
  }) {
    return Navigator.of(context).pushNamed<T>(routeName, arguments: arguments);
  }

2.2.2 配置使用

s1.通用路由配置类

class TestRouter {
  // 此处用于后续通用路由配置
  static Map<String, Function> routes = {
    TestRouterPage.routeName: (context) => const TestRouterPage(),
  };

  // 配置到MaterialApp的onGenerateRoute中
  var onGenerateRoute = (RouteSettings settings) {
    final String? name = settings.name;
    final Function? pageBuilder = routes[name];
    if (pageBuilder != null) {      
      if (settings.arguments != null) {
        // 带参数路由
        final Route route = MaterialPageRoute(builder: (context) => pageBuilder(context), settings: settings);
        return route;
      } else {
        // 无参数路由
        final Route route = MaterialPageRoute(builder: (context) => pageBuilder(context));
        return route;
      }
    }
    return MaterialPageRoute(builder: (context) => WebPage(const Page404()));
  };
}

s2.路由配置类加到APP启动的MaterialApp的onGenerateRoute中

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(primaryColor: Colors.blue, primaryTextTheme: TextTheme()),
      onGenerateRoute: TestRouter().onGenerateRoute,
      home: const TestHomePage(),
    );
  }
}

2.2.3 使用演示

Navigator.pushNamed(context, TestRouterPage.routeName);

3 路由管理Navigator.pop

3.1 源码

  @optionalTypeArgs
  static void pop<T extends Object?>(BuildContext context, [ T? result ]) {
    Navigator.of(context).pop<T>(result);
  }

3.2 使用演示

从TestRouterConstructPage页面后退到TestHomePage。

class TestRouterConstructPage extends StatelessWidget {
  late Map _argu;
  TestRouterConstructPage(this._argu, {Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GestureDetector(
        child: Center(
            child: Container(
          alignment: Alignment.center,
          decoration: BoxDecoration(border: Border.all(width: 1, color: Colors.blue)),
          child: Text(
            "This is a router construct page. argMap = $_argu",
            textAlign: TextAlign.center,
            style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500, color: Colors.blue),
          ),
        )),
        onTap: () {
          Navigator.pop(context);
        },
      ),
    );
  }
}

4 Navigator.popUntil

4.1 源码

  static void popUntil(BuildContext context, RoutePredicate predicate) {
    Navigator.of(context).popUntil(predicate);
  }

4.2 使用演示

从TestRouterConstructPage页面后退到首页【TestHomePage】。

class TestRouterConstructPage extends StatelessWidget {
  late Map _argu;
  TestRouterConstructPage(this._argu, {Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GestureDetector(
        child: Center(
            child: Container(
          alignment: Alignment.center,
          decoration: BoxDecoration(border: Border.all(width: 1, color: Colors.blue)),
          child: Text(
            "This is a router construct page. argMap = $_argu",
            textAlign: TextAlign.center,
            style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500, color: Colors.blue),
          ),
        )),
        onTap: () {
          Navigator.popUntil(context, (route) => route.isFirst);
        },
      ),
    );
  }
}

跳转指定页

// 页面push跳转
Navigator.push(context, MaterialPageRoute(settings: const RouteSettings(name: "/TestHomePage"), builder: (context) => TestHomePage()));

// 页面pop跳转
Navigator.popUntil(context, ModalRoute.withName("/TestHomePage")),  

关于路由及Navigator.push和Navigator.pop的参数处理部分在下一节中继续详细说明。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容