【Flutter】路由组件的应用 (学习记录)

前言

在 Flutter 中,路由用于管理应用程序中不同页面之间的导航和跳转。Flutter 提供了多种方式来实现路由管理,包括基本的静态路由、动态路由、命名路由以及使用第三方库(如 GetX、Provider 等)来管理路由。

一、 静态路由(Static Routing)

MaterialApp 和 CupertinoApp 实现 静态路由的方式

1、静态路由是最基本的路由管理方式,通过在 MaterialApp 或 CupertinoApp 中使用 routes

参数来定义路由映射。每个路由都与一个页面组件相关联,可以通过路由名称来导航到相应的页面。

2、 MaterialApp 和 CupertinoApp 中使用 routes 的方式是相同的,在使用不同的组件只需要替换他们的组件名即可。

3、 他们唯一不同处,MaterialApp 使用 Material Design 风格的路由转场效果,例如页面从底部弹出、淡入淡出等效果,CupertinoApp 使用 iOS 风格的路由转场效果,例如页面从右侧滑入、从底部弹出等效果。

4、 例子:(这里只使用 MaterialApp 来写案例,CupertinoApp 和 MaterialApp 大同小异)

typescript 复制代码
main.dart(主文件):

import 'package:flutter/material.dart';
import 'package:your_app/route_config.dart';

void main() {
  runApp(MyApp());
};

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter App',
      initialRoute: '/',
      routes: RouteConfig.routes,
    );
  };
};




route_config.dart(路由配置文件):

import 'package:flutter/material.dart';
import 'package:your_app/screens/home_screen.dart';
import 'package:your_app/screens/page1_screen.dart';
import 'package:your_app/screens/page2_screen.dart';

class RouteConfig {
  static Map<String, WidgetBuilder> routes = {
    '/': (context) => HomeScreen(),
    '/page1': (context) => Page1Screen(),
    '/page2': (context) => Page2Screen(),
  };
}

GetMaterialApp 顶级组件中实现静态路由的方式

1、GetMaterialApp 是GetX 库中的组件,代替 Flutter 中的 MaterialApp,并使用 GetX 提供的方式来管理静态路由。

2、优点:

  • 简洁性:使用 GetX 的 GetMaterialApp 和 GetPage 可以让路由配置变得更加简洁和直观,通过简单的方式定义路由映射关系。
  • 便捷性:GetX 提供了便捷的路由管理方式,通过 Get.toNamed('/routeName') 可以快速实现页面之间的导航,简化了路由操作。
  • 状态管理:GetX 提供了强大的状态管理功能,可以与路由管理无缝集成,使得在页面之间共享状态变得更加容易。
  • 动态路由:虽然 GetX 的路由配置方式更接近静态路由,但仍然可以根据需要动态生成路由,实现灵活的路由管理。

3、缺点:

  • 灵活性:相比传统的命名路由方式,GetX 的静态路由管理方式可能在一些复杂场景下缺乏灵活性,特别是对于动态路由配置和复杂的路由跳转逻辑。
  • 学习曲线:对于新手来说,GetX 的路由管理方式可能需要一定的学习成本,需要熟悉 GetX 的 API 和路由配置方式。
  • 迁移成本:如果已有项目使用传统的命名路由管理方式,迁移到 GetX 的静态路由管理方式可能需要一定的迁移成本和工作量。

4、总结:使用 GetX 的 GetMaterialApp 实现静态路由管理方式在简洁性和便捷性方面具有优势,尤其适合中小型应用程序。然而,在复杂的应用程序中,可能需要权衡灵活性和学习曲线等因素,选择适合项目需求的路由管理方式

(getX 要通过单独下载依赖包才能使用)。

5、例子:

typescript 复制代码
main.dart(主文件):

import 'package:flutter/material.dart';
import 'package:making_friends/router/index.dart';
import 'package:get/get_navigation/src/root/get_material_app.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        // 配置默认进入的页面路由路径
        initialRoute: '/',
        getPages: getXRouters,
    );
  }
}



router/index.dart(路由配置):

import 'dart:core';
import './route_key.dart';
import 'package:get/get.dart';

//[getX]路由配置
final List<GetPage> getXRouters = RouteKey.routes.map((route) {
  return GetPage(
    name: route.name,
    page: route.page,
  );
}).toList();



router/route_key.dart(路由目录):

// 资源
import 'package:flutter/cupertino.dart';
// 页面
import 'package:making_friends/view/Home/index.dart';
import 'package:making_friends/view/Login/index.dart';

class RouteInfo {
  final String name;
  final Widget Function() page;
  RouteInfo({required this.name, required this.page});
}

class RouteKey {
  RouteKey._();
  static List<RouteInfo> routes = [
    // 登录
    RouteInfo(name: '/login', page: () => const Login()),
  //   首页
    RouteInfo(name: '/', page: () => const Home()),
  ];
}
二、 命名路由(Named Routing):

MaterialApp 和 CupertinoApp 实现 命名路由的方式

1、命名路由是一种更灵活和可扩展的路由管理方式,通过使用 Navigator 类的方法来实现页面之间的导航。可以在任何地方使用命名路由来跳转到指定的页面。

2、MaterialApp 和 CupertinoApp 实现的方式是一样的,这里的案例只写一种,里面的配置方式也可以单独写一个文件进行引入使用,在任意跳转的地方使用 Navigator.pushNamed(context, '/page1'); 的方式进行跳转页面。

3、例子:

typescript 复制代码
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:your_app/screens/home_screen.dart';
import 'package:your_app/screens/page1_screen.dart';
import 'package:your_app/screens/page2_screen.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter App',
      initialRoute: '/',
      onGenerateRoute: (settings) {
        switch (settings.name) {
          case '/':
            return MaterialPageRoute(builder: (context) => HomeScreen());
          case '/page1':
            return MaterialPageRoute(builder: (context) => Page1Screen());
          case '/page2':
            return MaterialPageRoute(builder: (context) => Page2Screen());
          default:
            return null;
        }
      },
    );
  }
}

GetMaterialApp 顶级组件中实现命名路由的方式

1、在 GetX 中,虽然使用 GetMaterialApp 和 GetPage 来管理路由,但实际上 GetX 并没有提供专门的命名路由的概念。

2、在 GetX 中,使用 GetPage 来定义路由时,可以通过路由名称来访问页面,但这并不是传统意义上的命名路由。

3、在 GetX 中,路由的定义方式更接近静态路由的概念,通过在 getPages 中定义路由映射关系来实现页面之间的导航。

4、虽然在 GetX 中没有严格意义上的命名路由,但仍然可以使用 Get.toNamed('/routeName') 来实现类似命名路由的效果。

5、因此,在 GetX 中,使用 GetMaterialApp 和 GetPage 来定义路由时,实际上更接近静态路由的管理方式,而不是传统意义上的命名路由。

三、 动态路由(Dynamic Routing):

MaterialApp 和 CupertinoApp 实现动态路由的方式

1、MaterialApp 和 CupertinoApp 实现动态路由还是通过命名路由的方式,进行通过条件判断跳转的页面。

2、动态路由通常指根据用户输入或应用程序状态动态决定导航目标的路由管理方式。

3、所以说还是根据路由的给入得状态来进行实现的。

4、例子:

typescript 复制代码
// 在 MaterialApp 中实现动态路由:
import 'package:flutter/material.dart';
import 'package:your_app/screens/home_screen.dart';
import 'package:your_app/screens/page1_screen.dart';
import 'package:your_app/screens/page2_screen.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  String dynamicRoute = '/page1'; // 根据条件动态选择路由名称

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter App',
      initialRoute: '/',
      onGenerateRoute: (settings) {
        switch (settings.name) {
          case '/':
            return MaterialPageRoute(builder: (context) => HomeScreen());
          case '/page1':
            return MaterialPageRoute(builder: (context) => Page1Screen());
          case '/page2':
            return MaterialPageRoute(builder: (context) => Page2Screen());
          default:
            return MaterialPageRoute(builder: (context) => HomeScreen());
        }
      },
    );
  }
}

//在 CupertinoApp 中实现动态路由:
import 'package:flutter/cupertino.dart';
import 'package:your_app/screens/home_screen.dart';
import 'package:your_app/screens/page1_screen.dart';
import 'package:your_app/screens/page2_screen.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  String dynamicRoute = '/page2'; // 根据条件动态选择路由名称

  @override
  Widget build(BuildContext context) {
    return CupertinoApp(
      home: Builder(
        builder: (context) {
          switch (dynamicRoute) {
            case '/':
              return HomeScreen();
            case '/page1':
              return Page1Screen();
            case '/page2':
              return Page2Screen();
            default:
              return Container();
          }
        },
      ),
    );
  }
}

GetMaterialApp 实现动态路由的方式

1、在 GetX 中,可以使用 GetMaterialApp 来实现动态路由。通过在 GetMaterialApp 中使用 GetX 提供的路由管理方式,可以根据条件动态选择要跳转的路由。

2、根据条件动态选择要跳转的路由名称,并将其作为 GetMaterialApp 的 initialRoute 参数传入,实现了根据条件动态选择路由的效果。通过使用 GetX 的 GetMaterialApp 和 GetPage,可以更加灵活地管理动态路由,实现页面之间的导航和跳转。

3、例子:

typescript 复制代码
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:your_app/screens/home_screen.dart';
import 'package:your_app/screens/page1_screen.dart';
import 'package:your_app/screens/page2_screen.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  String dynamicRoute = '/page1'; // 根据条件动态选择路由名称

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'Flutter App',
      initialRoute: '/',
      getPages: [
        GetPage(name: '/', page: () => HomeScreen()),
        GetPage(name: '/page1', page: () => Page1Screen()),
        GetPage(name: '/page2', page: () => Page2Screen()),
      ],
      initialRoute: dynamicRoute,
    );
  }
}
四、 路由状态管理以及页面跳转如何传参
路由状态管理:

1、 MaterialApp 中的路由状态管理:

  • 在 MaterialApp 中,通过 routes 参数和 onGenerateRoute 方法来管理路由状态。
  • routes 参数用于静态路由映射,指定路由名称与页面组件的对应关系。
  • onGenerateRoute 方法用于动态生成路由,根据路由名称返回对应的页面组件。

2、CupertinoApp 中的路由状态管理:

  • 在 CupertinoApp 中,通过 onGenerateRoute 方法来管理路由状态。
  • onGenerateRoute 方法用于根据路由名称动态生成路由,返回对应的页面组件。

3、GetMaterialApp 中的路由状态管理:

  • 使用 GetMaterialApp 来管理应用程序的路由状态。
    • 在 getPages 中定义路由映射关系,将路由名称与页面构建函数关联起来。
页面之间的数据传递:

1、MaterialApp 和 CupertinoApp 页面跳转传参:

  • 在路由生成时,根据路由名称判断是否是特定页面,如果是,则创建页面组件时传递参数。
  • 通过 settings.arguments 获取传递的参数,并将参数传递给目标页面组件。

2、GetMaterialApp 页面跳转传参:

  • 在目标页面的构建函数中,可以通过 GetX 提供的方式来获取传递的参数。
  • 例如,可以在目标页面的构建函数中使用 Get.arguments 来获取传递的参数。
    例子:(路由状态管理和页面跳转传参的方式,以及路由跳转接收参数的方式)
typescript 复制代码
// MaterialApp 中的路由状态管理和页面跳转传参:
import 'package:flutter/material.dart';
import 'package:your_app/screens/home_screen.dart';
import 'package:your_app/screens/details_screen.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter App',
      initialRoute: '/',
      routes: {
        '/': (context) => HomeScreen(),
        '/details': (context) => DetailsScreen(),
      },
      onGenerateRoute: (settings) {
        if (settings.name == '/details') {
          return MaterialPageRoute(builder: (context) => DetailsScreen(data: settings.arguments));
        }
        return null;
      },
    );
  }
}

// MaterialApp 传参中页面接收参数的方式:
class DetailsScreen extends StatelessWidget {
  final String data;

  DetailsScreen({this.data});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Details Screen'),
      ),
      body: Center(
        child: Text('Received Data: $data'),
      ),
    );
  }
}




// CupertinoApp 中的路由状态管理和页面跳转传参:
import 'package:flutter/cupertino.dart';
import 'package:your_app/screens/home_screen.dart';
import 'package:your_app/screens/details_screen.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CupertinoApp(
      home: HomeScreen(),
      onGenerateRoute: (settings) {
        if (settings.name == '/details') {
          return CupertinoPageRoute(builder: (context) => DetailsScreen(data: settings.arguments));
        }
        return null;
      },
    );
  }
}

// CupertinoApp 传参中页面接收参数的方式:
class DetailsScreen extends StatelessWidget {
  final String data;

  DetailsScreen({this.data});

  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      navigationBar: CupertinoNavigationBar(
        middle: Text('Details Screen'),
      ),
      child: Center(
        child: Text('Received Data: $data'),
      ),
    );
  }
}




// GetMaterialApp 中的路由状态管理和页面跳转传参:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:your_app/screens/home_screen.dart';
import 'package:your_app/screens/details_screen.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'Flutter App',
      initialRoute: '/',
      getPages: [
        GetPage(name: '/', page: () => HomeScreen()),
        GetPage(name: '/details', page: () => DetailsScreen()),
      ],
      onGenerateRoute: (settings) {
        if (settings.name == '/details') {
          return GetPageRoute(
            page: () => DetailsScreen(data: settings.arguments),
          );
        }
        return null;
      },
    );
  }
}

// GetMaterialApp 传参中页面接收参数的方式:
class DetailsScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final dynamic data = Get.arguments; // 通过 Get.arguments 获取传递的参数

    return Scaffold(
      appBar: AppBar(
        title: Text('Details Screen'),
      ),
      body: Center(
        child: Text('Received Data: $data'),
      ),
    );
  }
}

文章是在学习阶段总结的,可能出现很多纰漏,请大家多多指正和提出建议性的修改。

相关推荐
JarvanMo10 小时前
关于Flutter架构的小小探讨
前端·flutter
顾林海10 小时前
Flutter 图标和按钮组件
android·开发语言·前端·flutter·面试
yzwdzkn12 小时前
解决Flutter 2.10.5在升级Xcode 16后的各种报错
flutter·macos·xcode
亚洲小炫风14 小时前
flutter json解析增强
flutter·json·json兼容格式
SY.ZHOU14 小时前
Flutter 与原生通信
android·flutter·ios
恋猫de小郭17 小时前
IntelliJ IDEA 2025.1 发布 ,默认 K2 模式 | Android Studio 也将跟进
android·前端·flutter
梦想不只是梦与想18 小时前
鸿蒙系统开发状态更新字段区别对比
android·java·flutter·web·鸿蒙
RichardLai8818 小时前
[Flutter学习之Dart基础] - 集合(List, Set,Map)
android·flutter
bst@微胖子18 小时前
Flutter项目之设置页
android·javascript·flutter