Flutter之路由监听器

RouteListenerManager 路由监听管理器

概述

RouteListenerManager 是一个用于管理Flutter应用路由监听器的单例类,它提供了统一的路由事件监听和通知机制。该管理器配合 GlobalRouteObserver 类,能够全局监听应用的路由变化,包括路由跳转、返回、替换和移除等操作。

核心特性

  • 单例模式:确保全局只有一个路由监听管理器实例

  • 多种路由事件监听:支持路由跳转、返回、替换、移除四种事件类型

  • 异常处理:监听器执行过程中的异常不会影响其他监听器

  • 全局路由观察 :通过 GlobalRouteObserver 自动捕获所有路由变化

  • 灵活管理:支持动态添加、移除监听器

类结构

RouteListenerManager

单例实现
dart 复制代码
static final RouteListenerManager _instance = RouteListenerManager._internal();

factory RouteListenerManager() => _instance;

static RouteListenerManager get instance => _instance;

RouteListenerManager._internal();
监听器存储
  • _pushListeners: 路由跳转监听器列表

  • _popListeners: 路由返回监听器列表

  • _replaceListeners: 路由替换监听器列表

  • _removeListeners: 路由移除监听器列表

API 文档

监听器管理方法

添加监听器
addPushListener
dart 复制代码
void addPushListener(Function(String route) listener)
  • 功能:添加路由跳转监听器

  • 参数listener - 接收路由名称的回调函数

  • 用途:当发生路由跳转时触发

addPopListener
dart 复制代码
void addPopListener(Function(String route) listener)
  • 功能:添加路由返回监听器

  • 参数listener - 接收路由名称的回调函数

  • 用途:当发生路由返回时触发

addReplaceListener
dart 复制代码
void addReplaceListener(Function(String newRoute, String oldRoute) listener)
  • 功能:添加路由替换监听器

  • 参数listener - 接收新路由名称和旧路由名称的回调函数

  • 用途:当发生路由替换时触发

addRemoveListener
dart 复制代码
void addRemoveListener(Function(String route) listener)
  • 功能:添加路由移除监听器

  • 参数listener - 接收路由名称的回调函数

  • 用途:当发生路由移除时触发

移除监听器
removePushListener
dart 复制代码
void removePushListener(Function(String route) listener)
  • 功能:移除指定的路由跳转监听器
removePopListener
dart 复制代码
void removePopListener(Function(String route) listener)
  • 功能:移除指定的路由返回监听器
removeReplaceListener
dart 复制代码
void removeReplaceListener(Function(String newRoute, String oldRoute) listener)
  • 功能:移除指定的路由替换监听器
removeRemoveListener
dart 复制代码
void removeRemoveListener(Function(String route) listener)
  • 功能:移除指定的路由移除监听器
removeAllListener
dart 复制代码
void removeAllListener()
  • 功能:移除所有类型的监听器

  • 用途:清理所有监听器,通常在应用退出时调用

通知方法
notifyPush
dart 复制代码
void notifyPush(String route)
  • 功能:通知所有路由跳转监听器

  • 异常处理:单个监听器异常不会影响其他监听器执行

notifyPop
dart 复制代码
void notifyPop(String route)
  • 功能:通知所有路由返回监听器

  • 异常处理:单个监听器异常不会影响其他监听器执行

notifyReplace
dart 复制代码
void notifyReplace(String newRoute, String oldRoute)
  • 功能:通知所有路由替换监听器

  • 异常处理:单个监听器异常不会影响其他监听器执行

notifyRemove
dart 复制代码
void notifyRemove(String route)
  • 功能:通知所有路由移除监听器

  • 异常处理:单个监听器异常不会影响其他监听器执行

GlobalRouteObserver

类定义
dart 复制代码
class GlobalRouteObserver extends NavigatorObserver
重写方法
didPush
dart 复制代码
void didPush(Route<dynamic> route, Route<dynamic>? previousRoute)
  • 功能:监听路由跳转事件

  • 实现 :提取路由名称并调用 RouteListenerManager().notifyPush()

  • 日志:输出路由跳转信息

didPop
dart 复制代码
void didPop(Route<dynamic> route, Route<dynamic>? previousRoute)
  • 功能:监听路由返回事件

  • 实现 :提取路由名称并调用 RouteListenerManager().notifyPop()

  • 日志:输出路由返回信息

didReplace
dart 复制代码
void didReplace({Route<dynamic>? newRoute, Route<dynamic>? oldRoute})
  • 功能:监听路由替换事件

  • 实现 :提取新旧路由名称并调用 RouteListenerManager().notifyReplace()

  • 日志:输出路由替换信息

  • 安全检查:确保新旧路由都不为空

didRemove
dart 复制代码
void didRemove(Route<dynamic> route, Route<dynamic>? previousRoute)
  • 功能:监听路由移除事件

  • 实现 :提取路由名称并调用 RouteListenerManager().notifyRemove()

  • 日志:输出路由移除信息

使用示例

1. 基本使用

dart 复制代码
// 获取管理器实例

final routeManager = RouteListenerManager.instance;

  


// 添加路由跳转监听器

routeManager.addPushListener((String route) {

  print('路由跳转到: $route');

  // 执行自定义逻辑,如埋点统计、页面预加载等

});

  


// 添加路由返回监听器

routeManager.addPopListener((String route) {

  print('从路由返回: $route');

  // 执行自定义逻辑,如清理资源、保存状态等

});

  


// 添加路由替换监听器

routeManager.addReplaceListener((String newRoute, String oldRoute) {

  print('路由替换: $oldRoute -> $newRoute');

  // 执行自定义逻辑

});

2. 在MaterialApp中注册全局观察者

dart 复制代码
class MyApp extends StatelessWidget {

  @override

  Widget build(BuildContext context) {

    return MaterialApp(

      navigatorObservers: [

        GlobalRouteObserver(), // 注册全局路由观察者

      ],

      // 其他配置...

    );

  }

}

3. 动态管理监听器

dart 复制代码
class MyPage extends StatefulWidget {

  @override

  _MyPageState createState() => _MyPageState();

}

  


class _MyPageState extends State<MyPage> {

  late Function(String) routeListener;

  


  @override

  void initState() {

    super.initState();

    

    // 创建监听器

    routeListener = (String route) {

      print('页面 $route 被访问');

    };

    

    // 添加监听器

    RouteListenerManager.instance.addPushListener(routeListener);

  }

  


  @override

  void dispose() {

    // 移除监听器,避免内存泄漏

    RouteListenerManager.instance.removePushListener(routeListener);

    super.dispose();

  }

}

4. 清理所有监听器

dart 复制代码
// 在应用退出时清理所有监听器

void cleanup() {

  RouteListenerManager.instance.removeAllListener();

}

设计模式

单例模式

  • 确保全局只有一个 RouteListenerManager 实例

  • 通过私有构造函数和静态实例实现

  • 提供工厂构造函数和静态getter两种访问方式

观察者模式

  • RouteListenerManager 作为主题(Subject)

  • 各种监听器作为观察者(Observer)

  • 当路由事件发生时,自动通知所有注册的观察者

策略模式

  • 不同类型的路由事件使用不同的处理策略

  • 通过函数回调实现灵活的事件处理逻辑

异常处理

所有通知方法都包含异常处理机制:

dart 复制代码
void notifyPush(String route) {

  for (final listener in _pushListeners) {

    try {

      listener(route);

    } catch (e) {

      debugPrint('Route push listener error: $e');

    }

  }

}
  • 单个监听器的异常不会影响其他监听器的执行

  • 异常信息会通过 debugPrint 输出到控制台

  • 确保系统的稳定性和可靠性

注意事项

  1. 内存管理:及时移除不再需要的监听器,避免内存泄漏

  2. 异常处理:监听器函数应该处理可能的异常情况

  3. 性能考虑:避免在监听器中执行耗时操作

  4. 线程安全:当前实现不是线程安全的,如需多线程访问请添加同步机制

  5. 路由名称:确保路由有明确的名称,避免使用 'unknown' 作为路由名称

扩展建议

  1. 添加路由参数传递:支持传递路由参数给监听器

  2. 添加条件监听:支持基于条件的监听器注册

  3. 添加优先级机制:支持监听器的优先级排序

  4. 添加异步支持:支持异步监听器函数

  5. 添加统计功能:添加路由访问统计和分析功能

总结

RouteListenerManager 提供了一个强大而灵活的路由监听机制,通过单例模式和观察者模式的结合,实现了全局路由事件的统一管理。该设计具有良好的扩展性和维护性,能够满足大多数Flutter应用的路由监听需求。

相关推荐
三翼鸟数字化技术团队2 小时前
2025前端技术趋势:从智能到沉浸的新时代
前端·ai编程
恋猫de小郭2 小时前
Android 17 有什么需要适配的?2026 Android 禁止侧载又是什么?
android·前端·flutter
Never_Satisfied2 小时前
在HTML & CSS中,如何计算CSS特异性
前端·css·html
阿林来了2 小时前
Flutter三方库适配OpenHarmony【flutter_web_auth】— EntryAbility 深度链接回调集成
flutter
滕青山2 小时前
网页源代码查看在线工具 核心JS实现
前端·javascript·vue.js
www_stdio2 小时前
项目基础准备之Zustand:轻量级 React 状态管理的优雅之选
前端·react.js·typescript
阿林来了2 小时前
Flutter三方库适配OpenHarmony【flutter_web_auth】— OpenHarmony 插件工程搭建与配置文件详解
flutter·harmonyos
躲在云朵里`2 小时前
同一账号在同一客户端类型只能登录一次
前端·spring·bootstrap
2601_949593652 小时前
Flutter for Harmony 跨平台开发实战:递归分形树——L-系统的生长逻辑
flutter