Flutter中GetX搭配AutoRoute时Get.context为空的问题
解决Flutter中GetX与AutoRoute结合时Get.context为null的问题
问题现象
在Flutter项目中同时使用GetX框架和AutoRoute实现导航时,组件内的Get.context始终为null,调用Get.width这类依赖上下文的API会直接引发崩溃。
复现环境
- Flutter 3.13.4
- GetX 4.6.6
- AutoRoute 7.8.3
复现代码
pubspec.yml
name: testtest description: A new Flutter project. publish_to: 'none' version: 1.0.0+1 environment: sdk: '3.1.2' dependencies: flutter: sdk: flutter cupertino_icons: 1.0.2 get: 4.6.6 auto_route: 7.8.3 dev_dependencies: flutter_test: sdk: flutter flutter_lints: 2.0.0 auto_route_generator: 7.3.1 build_runner: flutter: uses-material-design: true
lib/main.dart
import 'package:flutter/material.dart'; import 'package:auto_route/auto_route.dart'; import 'package:get/get_navigation/src/root/get_material_app.dart'; import 'package:testtest/home_screen.dart'; import 'main.gr.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { MyApp({super.key}); final _appRouter = AppRouter(); @override Widget build(BuildContext context) { return GetMaterialApp.router( // (1) title: 'Flutter Demo', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), routerDelegate: _appRouter.declarativeDelegate(routes: (handler) => [HomeRoute()],), // (2) routeInformationParser: _appRouter.defaultRouteParser(), // (3) // home: HomeScreen(), // (4) ); } } @AutoRouterConfig() class AppRouter extends $AppRouter { @override List<AutoRoute> get routes => [ AutoRoute(path: "/HomeRoute", page: HomeRoute.page), ]; }
lib/home_screen.dart
import 'package:auto_route/annotations.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @RoutePage() class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @override State<HomeScreen> createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { @override Widget build(BuildContext context) { double? width = null; try { width = Get.width; }catch(_){} return Scaffold( body: SafeArea(child: Text( """Context: ${Get.context?.toString() ?? "null"} width: ${width ?? "Error"} """) ), ); } }
代码生成命令
flutter packages pub run build_runner build
运行结果
运行后屏幕显示:
Context: null width: Error
若将GetMaterialApp.router改为普通的GetMaterialApp,注释(2)(3)行并启用(4)行(不使用AutoRoute),Get.context可正常获取,Get.width返回正确值。
问题原因
GetX的全局上下文(Get.context)依赖于自身的路由管理系统来维护,当使用AutoRoute的declarativeDelegate时,页面路由由AutoRoute独立管理,并没有纳入GetX的路由栈中,导致GetX无法捕获到当前页面的上下文。
解决方案
将AutoRoute的路由栈嵌套到GetX的上下文体系中,修改main.dart中的MyApp组件:
class MyApp extends StatelessWidget { MyApp({super.key}); final _appRouter = AppRouter(); @override Widget build(BuildContext context) { return GetMaterialApp( title: 'Flutter Demo', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), home: RouterScope( controller: _appRouter, child: AutoRouter(), ), ); } }
同时修改AppRouter的路由配置,设置初始路由:
@AutoRouterConfig() class AppRouter extends $AppRouter { @override List<AutoRoute> get routes => [ AutoRoute(path: "/", page: HomeRoute.page, initial: true), ]; }
这样修改后,AutoRoute的页面会被包裹在GetX的上下文环境中,Get.context就能正常获取,Get.width等API也能正常工作。
临时替代方案(不推荐)
在页面的build方法中手动将当前上下文绑定到GetX,但这种方式不够优雅,且可能引发上下文生命周期问题:
@override Widget build(BuildContext context) { Get.context = context; // 手动绑定上下文 double width = Get.width; return Scaffold(...); }
内容的提问来源于stack exchange,提问作者Vít Skalický
相关产品推荐
相关产品推荐

