我现在遇到了一个问题,那就是在我的Flutter 翼应用程序中无法访问Navigator.代码是这样的:

class App extends StatelessWidget {
  const App({super.key});

  @override
  Widget build(BuildContext context) {
    return MultiBlocProvider(
      providers: [
        BlocProvider<LanguageBloc>(
          create: (_) => serviceLocator<LanguageBloc>(),
        ),
        BlocProvider<MaintenanceBloc>(
          create: (_) => serviceLocator<MaintenanceBloc>(),
        ),
        BlocProvider<VersionBloc>(
          create: (_) => serviceLocator<VersionBloc>(),
        ),
        BlocProvider<AuthBloc>(
          create: (_) => serviceLocator<AuthBloc>(),
        ),
      ],
      child: const _AppView(),
    );
  }
}

class _AppView extends StatefulWidget {
  const _AppView();

  @override
  State<_AppView> createState() => _AppViewState();
}

class _AppViewState extends State<_AppView> {
  final _navigatorKey = GlobalKey<NavigatorState>();

  NavigatorState get _navigator => _navigatorKey.currentState!;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey: _navigatorKey,
      title: AppConfig.appName,
      locale: context.select((LanguageBloc bloc) => bloc.state.language.toLocale()),
      supportedLocales: AppLanguage.toLocales(),
      localizationsDelegates: [
        AppLocalization.getDelegate(getAppTranslations: serviceLocator<GetAppTranslations>()),
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      theme: AppTheme.themeData,
      onGenerateRoute: (settings) {
        return MaterialPageRoute(
          settings: settings,
          builder: (context) {
            return const Placeholder(
              color: Colors.red,
            );
          },
        );
      },
      builder: (context, child) {
        return MultiBlocListener(
          listeners: [
            BlocListener<MaintenanceBloc, MaintenanceState>(
              listener: (context, state) {
                switch (state.runtimeType) {
                  case InMaintenance:
                    _navigator.pushAndRemoveUntil<void>(
                      MaterialPageRoute(builder: (context) => const MaintenancePage()),
                      (route) => false,
                    );
                    break;
                  case NotInMaintenance:
                    break;
                }
              },
            ),
            BlocListener<VersionBloc, VersionState>(
              listener: (context, state) {
                switch (state.runtimeType) {
                  case InitialVersionState:
                    break;
                  case CheckingVersion:
                    break;
                  case Outdated:
                    _navigator.pushAndRemoveUntil<void>(
                      MaterialPageRoute(builder: (context) => const OutdatedPage()),
                      (route) => false,
                    );
                    break;
                  case UpToDate:
                    break;
                }
              },
            ),
            BlocListener<AuthBloc, AuthState>(
              listener: (context, state) {
                switch (state.status) {
                  case AuthStatus.authenticated:
                    _navigator.pushAndRemoveUntil<void>(
                      MaterialPageRoute(builder: (context) => MainPage()),
                      (route) => false,
                    );
                  case AuthStatus.unauthenticated:
                    _navigator.pushAndRemoveUntil<void>(
                      MaterialPageRoute(builder: (context) => const LoginPage()),
                      (route) => false,
                    );
                  case AuthStatus.unknown:
                    _navigator.pushAndRemoveUntil<void>(
                      MaterialPageRoute(builder: (context) => const LoginPage()),
                      (route) => false,
                    );
                }
              },
            ),
          ],
          child: child!,
        );
      },
    );
  }
}

使用我的代码,我基本上遵循了您在BLoC Login Tutorial中看到的代码.

无论出于什么原因,这都会导致Unhandled Exception: Null check operator used on a null valueNavigatorState get _navigator => _navigatorKey.currentState!;,这意味着Navigator不能被访问.

当我运行相同的代码,但没有使用_navigatorKey,而是使用Navigator.of(context)时,我收到以下错误:

Unhandled Exception: Navigator operation requested with a context that does not include a Navigator.

The context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget.

再次表明我不能使用Navigator.

这一点让我感到困惑,因为MaterialApp是一个parent小部件,所以Navigator应该是可访问的.将MultiBlocListener包装在Builder中以获得最新的context并不能解决问题.不使用MultiBlocListener内部的独立BlocListener提供的context也没有帮助.

在这个阶段,我不知道这里出了什么问题,特别是因为我正在遵循上面链接的教程.

推荐答案

我认为,自编写本教程以来,API已经发生了变化.

密钥位于MaterialApp https://api.flutter.dev/flutter/material/MaterialApp-class.html#builderbuilder属性的文档中

A builder for inserting widgets above the Navigator.

因此,所有的BlocListeners都被插入到树中导航器的上方,这意味着它们永远不能从上下文中获得对导航器的任何类型的引用.

Flutter相关问答推荐

如何在应用栏中将列置于中心

如何更新文本字段的基础上的选定下拉菜单?

Ffltter:发布版本中的Path NotFoundException

无法在我的Flutter 应用程序中使用GoRouter测试导航

为什么当我使用Riverpod更新状态时,列表会被刷新?

如何使用flutter_local_notification包处理通知操作?

Wired Firebase错误-[CLOUD_FIRESTORE/UNAvailable]该服务当前不可用

如何将WebViewWidget和WillPopScope结合起来

如何手动将 FirebaseAuth 用户邮箱验证状态设置为 true

Flutter:如何在 Future 函数上添加网络判断和 showDialog

在 Flutter 中解码 BLE 设备负载

如何从Firebase登录获取用户信息,如电话号码、出生日期和性别

Riverpod 注册多少个 providers

在Flutter中为容器实现线性渐变背景动画

无法将Null类型的值分配给 const 构造函数中List类型的参数

你如何在 Flutter 中组合两个数组?

type '({bool growable}) => List' 不是类型转换中类型 'List' 的子类型

在 Flutter Bloc 中具有称为 status 的属性的一种状态或不同的状态,哪个更可取?

Flutter_riverpod 安装时出现问题

如何在 Flutter 中创建类似箭头标签的设计