• Flutter 路由


    路由简介


    Route
    一个路由是一个屏幕或页面的抽象

    Navigator
    管理路由的组件,Navigator 可以通过路由入栈和出栈来实现页面之间的跳转

    常用属性:
    initialRoute:初始路由,即默认页面
    onGenerateRoute:动态路由(根据规则,匹配动态路由)
    onUnknownRoute:未知路由,也就是404
    routes:路由集合

    匿名路由

    Navigator
      push():跳转到指定组件
    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) => 组件名称(),
        settings: const RouteSettings(
          name: String, // 路由名称
          arguments: {
            String: dynamic, // 参数
          },
        ),
      )
    )
    pop():回退
    Navigator.pop(context)

    示例:

    import 'package:flutter/material.dart';
    import '08_navigator/navigator_01_anonymous.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: "Flutter Demo",
          // home: Home(),
          // 声明路由
          routes: {
            'home': (context) => const Home(),
            'product': (context) => const Product(),
          },
          // 初始路由
          initialRoute: 'home',
          debugShowCheckedModeBanner: false,
        );
      }
    }
    import 'package:flutter/material.dart';
    
    // 首页
    class Home extends StatelessWidget {
      const Home({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('匿名路由'),
          ),
          body: ListView(
            padding: const EdgeInsets.all(10),
            children: [
              ElevatedButton(
                onPressed: () {
                  // 匿名路由跳转 --基本用法
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => const Product()),
                  );
                },
                child: const Text('跳转到商品页面'),
              ),
              ElevatedButton(
                onPressed: () {
                  // 匿名路由跳转 -- 传参方法 1
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => const Product(),
                      settings: const RouteSettings(
                        name: '带参数的商品页面', // 修改路由名称
                        arguments: {
                          'userName': 'zhangsan',
                          'age': 23,
                        },
                      ),
                    ),
                  );
                },
                child: const Text('跳转带传参 settings'),
              ),
              ElevatedButton(
                onPressed: () {
                  // 匿名路由跳转-- 传参方法 2
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => const ProductDetail(id: '123'),
                    ),
                  );
                },
                child: const Text('跳转带传参 属性'),
              ),
            ],
          ),
        );
      }
    }
    
    // 商品页
    class Product extends StatelessWidget {
      const Product({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        dynamic settings = ModalRoute.of(context)?.settings;
        print('settings: $settings');
        return Scaffold(
          appBar: AppBar(
            // 传参方法 1:通过 settings 接收参数
            title: Text(settings?.name == null ? '商品页面' : settings.name),
          ),
          body: ListView(
            padding: const EdgeInsets.all(10),
            children: [
              Text(
                // 传参方法 1:通过 settings 接收参数
                '主页传递的参数是: ${settings.arguments}',
                style: const TextStyle(
                  fontSize: 26,
                  color: Colors.red,
                ),
              ),
              ElevatedButton(
                onPressed: () {
                  // 回退
                  return Navigator.pop(context);
                },
                child: const Text('返回'),
              ),
            ],
          ),
        );
      }
    }
    
    // 商品详情
    class ProductDetail extends StatelessWidget {
      final String id;
      const ProductDetail({
        Key? key,
        required this.id,
      }) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('商品详情'),
          ),
          body: ListView(
            padding: const EdgeInsets.all(10),
            children: [
              // 传参方法 2:通过 类属性 接收参数
              Text(
                '主页传递的参数是: $id',
                style: const TextStyle(
                  fontSize: 26,
                  color: Colors.red,
                ),
              ),
              ElevatedButton(
                onPressed: () {
                  // 回退
                  return Navigator.pop(context);
                },
                child: const Text('返回'),
              ),
            ],
          ),
        );
      }
    }

    命名路由

    (1)、声明路由
    routes:路由表(Map类型)
    initialRoute:初始路由
    onUnknownRoute:未知路由 - 404

    (2)、跳转到命名路由
    Navigator.pushNamed(context, '路由名称');

    示例:

    import 'package:flutter/material.dart';
    import '08_navigator/navigator_02_namedRoute.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: "Flutter Demo",
          // home: Home(),
          // 声明路由
          routes: {
            'home': (context) => const Home(),
            'product': (context) => const Product(),
          },
          // 初始路由
          initialRoute: 'home',
          // 未知路由
          onUnknownRoute: (RouteSettings setting) => MaterialPageRoute(
            builder: (context) => const UnknownPage(),
          ),
          // 动态路由
          debugShowCheckedModeBanner: false,
        );
      }
    }
    import 'package:flutter/material.dart';
    
    // 首页
    class Home extends StatelessWidget {
      const Home({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('命名路由'),
          ),
          body: ListView(
            padding: const EdgeInsets.all(10),
            children: [
              ElevatedButton(
                // 命名路由跳转
                onPressed: () => Navigator.pushNamed(context, 'product'),
                child: const Text('跳转到商品页面'),
              ),
              // 命名路由传参
              ElevatedButton(
                // 命名路由跳转
                onPressed: () => Navigator.pushNamed(
                  // 上下文
                  context,
                  // 路由名称
                  'product',
                  // 参数
                  arguments: <String, dynamic>{
                    "title": "我是首页传过来的参数",
                    "age": 28,
                    "viewFlag": true,
                  },
                ),
                child: const Text('跳转到商品页面带入参'),
              ),
              // 未知路由跳转
              ElevatedButton(
                // 命名路由跳转
                onPressed: () => Navigator.pushNamed(context, 'user'),
                child: const Text('跳转到不存在的路由'),
              ),
            ],
          ),
        );
      }
    }
    
    // 商品
    class Product extends StatelessWidget {
      const Product({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        // 接收传参,可能是 null
        final arguments = ModalRoute.of(context)!.settings.arguments;
        return Scaffold(
          appBar: AppBar(
            title: const Text('商品页面'),
          ),
          body: ListView(
            padding: const EdgeInsets.all(10),
            children: [
              // 参数
              Text(
                '接收的参数是:$arguments',
                style: const TextStyle(
                  fontSize: 26,
                  color: Colors.red,
                ),
              ),
              ElevatedButton(
                onPressed: () {
                  // 返回
                  return Navigator.pop(context);
                },
                child: const Text('返回'),
              )
            ],
          ),
        );
      }
    }
    
    // 404
    class UnknownPage extends StatelessWidget {
      const UnknownPage({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('404'),
          ),
          body: Container(
            padding: const EdgeInsets.all(10),
            child: const Text('页面飞到太空去了……'),
          ),
        );
      }
    }

    动态路由

    动态路由是指通过 onGeneratedRoute 属性指定的路由

    示例:

    import 'package:flutter/material.dart';
    import '08_navigator/navigator_03_onGeneratedRoute.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: "Flutter Demo",
          // home: Home(),
          // 动态路由
          onGenerateRoute: (RouteSettings setting) {
            print('setting: $setting');
            print('当前路径:${setting.name}');
            // 匹配首页 /
            if (setting.name == '/') {
              return MaterialPageRoute(builder: (context) => const Home());
            }
            // 匹配商品页 /product
            if (setting.name == '/product') {
              return MaterialPageRoute(builder: (context) => const Product());
            }
            // 匹配商品详情页 /product/:id
            Uri uri = Uri.parse(setting.name ?? '');
            print('uri: $uri');
            if (uri.pathSegments.length == 2 &&
                uri.pathSegments.first == 'product') {
              String id = uri.pathSegments[1];
              return MaterialPageRoute(builder: (context) => ProductDetail(id: id));
            }
            return MaterialPageRoute(builder: (context) => const UnknownPage());
          },
          debugShowCheckedModeBanner: false,
        );
      }
    }
    import 'package:flutter/material.dart';
    
    class Home extends StatelessWidget {
      const Home({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('命名路由'),
          ),
          body: ListView(
            padding: const EdgeInsets.all(10),
            children: [
              ElevatedButton(
                // 命名路由跳转
                onPressed: () => Navigator.pushNamed(context, '/product'),
                child: const Text('跳转到商品页面'),
              ),
              ElevatedButton(
                // 命名路由跳转
                onPressed: () => Navigator.pushNamed(context, '/product/1'),
                child: const Text('商品1'),
              ),
              ElevatedButton(
                // 命名路由跳转
                onPressed: () => Navigator.pushNamed(context, '/product/2'),
                child: const Text('商品2'),
              ),
              // 未知路由跳转
              ElevatedButton(
                // 命名路由跳转
                onPressed: () => Navigator.pushNamed(context, '/product222'),
                child: const Text('跳转到不存在的路由'),
              ),
            ],
          ),
        );
      }
    }
    
    // 商品
    class Product extends StatelessWidget {
      const Product({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('商品页面'),
          ),
          body: Container(
            padding: const EdgeInsets.all(10),
            child: ElevatedButton(
              onPressed: () {
                return Navigator.pop(context);
              },
              child: const Text('返回'),
            ),
          ),
        );
      }
    }
    
    // 商品详情
    class ProductDetail extends StatelessWidget {
      final String id;
      const ProductDetail({
        Key? key,
        required this.id,
      }) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('商品详情'),
          ),
          body: ListView(
            padding: const EdgeInsets.all(10),
            children: [
              Text('当前商品的id是 $id'),
              ElevatedButton(
                onPressed: () {
                  return Navigator.pop(context);
                },
                child: const Text('返回'),
              ),
            ],
          ),
        );
      }
    }
    
    // 404
    class UnknownPage extends StatelessWidget {
      const UnknownPage({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('404'),
          ),
          body: Container(
            padding: const EdgeInsets.all(10),
            child: const Text('页面飞到太空去了……'),
          ),
        );
      }
    }

  • 相关阅读:
    第12组(78) 团队展示(组长)
    第一次结对编程作业
    Alpha冲刺总结
    第02组Alpha冲刺(6/6)
    第02组Alpha冲刺(5/6)
    第02组Alpha冲刺(4/6)
    第02组Alpha冲刺(3/6)
    第02组Alpha冲刺(2/6)
    第02组Alpha冲刺(1/6)
    第02组(51)需求分析报告
  • 原文地址:https://www.cnblogs.com/rogerwu/p/16312804.html
Copyright © 2020-2023  润新知