navigation_channel.dart 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter/services.dart';
  3. import 'package:go_router/go_router.dart';
  4. /// 平台(iOS/Android)主动下发路由时,通过此 Channel 传递给 Flutter。
  5. ///
  6. /// navigateTo:用 [GoRouter.go] 清空整个导航栈后跳转到目标路由。
  7. /// 配合 Android 端追加的 _ts 时间戳,确保缓存引擎下每次打开 Flutter 页面都重建 State。
  8. ///
  9. /// iOS 侧调用方式:
  10. /// ```objc
  11. /// [engine.navigationChannel invokeMethod:@"pushRouteInformation"
  12. /// arguments:@{@"location": @"/expense/apply"}];
  13. /// ```
  14. ///
  15. /// 或者通过自定义 channel:
  16. /// ```objc
  17. /// FlutterMethodChannel *ch = [FlutterMethodChannel
  18. /// methodChannelWithName:@"com.tboss.oa/navigation"
  19. /// binaryMessenger:engine.binaryMessenger];
  20. /// [ch invokeMethod:@"navigateTo" arguments:@"/expense/apply"];
  21. /// ```
  22. class NavigationChannel {
  23. static const _channel = MethodChannel('com.tboss.oa/navigation');
  24. /// 开始监听平台下发的导航指令。
  25. ///
  26. /// [router] 必须是已初始化的 GoRouter 实例。
  27. static void startListening(GoRouter router) {
  28. _channel.setMethodCallHandler((call) async {
  29. switch (call.method) {
  30. case 'navigateTo':
  31. final route = call.arguments as String?;
  32. if (route != null && route.isNotEmpty) {
  33. // 在 widget 树重建前先设置状态栏,避免缓存引擎二次打开时
  34. // Android Activity 主题覆盖 Flutter 的状态栏设置
  35. SystemChrome.setSystemUIOverlayStyle(
  36. const SystemUiOverlayStyle(
  37. statusBarColor: Colors.transparent,
  38. statusBarIconBrightness: Brightness.dark,
  39. ),
  40. );
  41. router.go(route);
  42. }
  43. break;
  44. case 'pushRoute':
  45. final route = call.arguments as String?;
  46. if (route != null && route.isNotEmpty) {
  47. router.push(route);
  48. }
  49. break;
  50. default:
  51. break;
  52. }
  53. });
  54. }
  55. }