GetX 状态管理的导航错误:

Navigation Error with GetX State Management:

我可以使用 Get.rootDelegate.toNamed 方法导航前两个屏幕(HomeMovie、HomeTvSeries)。但是当我尝试从其中任何一个导航到详细信息页面时,我收到了一个错误。我已经按照文档和示例进行操作,但找不到任何东西。知道我收到这个的原因是什么吗?

有效:

onPressed: () {
  Get.rootDelegate.toNamed(AppRoutes.HOME_MOVIE);
},

这不是:

onTap: () {
  Get.rootDelegate.toNamed(AppRoutes.DETAIL_MOVIE);
},

main.dart:

import 'package:device_preview/device_preview.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';

import '../../routes/index.dart';
import '../../util/index.dart';

Future<void> initServices() async {
  debugPrint('Starting GetX Services...');
  await GetStorage.init();
  await Get.putAsync(() => GlobalVariablesService().init());
  debugPrint('All GetX Services Started...');
}

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await initServices();

  runApp(
    DevicePreview(
      enabled: false,
      builder: (BuildContext context) => const MovieApp(),
    ),
  );
}

class MovieApp extends StatelessWidget {
  const MovieApp({
    Key? key,
  }) : super(key: key);

  static GlobalKey movieAppKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp.router(
      key: movieAppKey,
      debugShowCheckedModeBanner: false,
      title: 'Flutter The Movie DB',
      translations: GetTranslations(),
      locale: Get.deviceLocale,
      fallbackLocale: GetTranslations.fallbackLocale,
      theme: Style.lightTheme,
      darkTheme: Style.darkTheme,
      themeMode: ThemeMode.system,
      defaultTransition: Transition.cupertino,
      getPages: AppPages.routes,
      enableLog: true,
      //logWriterCallback: (String text, {bool isError = false}) {}
      navigatorObservers: <NavigatorObserver>[
        GetObserver(),
      ],
    );
  }
}

AppPages.dart:

import 'package:get/get.dart';

import '../../bindings/index.dart';
import '../../routes/index.dart';
import '../../ui/screens/index.dart';

class AppPages {
  static final List<GetPage<dynamic>> routes = <GetPage<dynamic>>[
    GetPage<dynamic>(
      name: AppRoutes.START,
      page: () => const StartScreen(),
      binding: StartBinding(),
      preventDuplicates: true,
      children: <GetPage<dynamic>>[
        GetPage<dynamic>(
          name: AppRoutes.HOME_MOVIE,
          page: () => const HomeMovieScreen(),
          transition: Transition.cupertino,
          binding: HomeMovieBinding(),
          children: <GetPage<dynamic>>[
            GetPage<dynamic>(
              name: AppRoutes.DETAIL_MOVIE,
              page: () => const DetailPage(),
              transition: Transition.cupertino,
              binding: DetailPageBinding(),
            ),
          ],
        ),
        GetPage<dynamic>(
          name: AppRoutes.HOME_TV,
          page: () => const HomeTvScreen(),
          transition: Transition.cupertino,
          binding: HomeTvBinding(),
          children: <GetPage<dynamic>>[
            GetPage<dynamic>(
              name: AppRoutes.DETAIL_TV,
              page: () => const DetailPage(),
              transition: Transition.cupertino,
              binding: DetailPageBinding(),
            ),
          ],
        ),
      ],
    ),
  ];
}

错误:

 ======== Exception caught by widgets library =======================================================
    The following assertion was thrown building Builder:
    'package:flutter/src/widgets/navigator.dart': Failed assertion: line 3619 pos 18: '!keyReservation.contains(key)': is not true.
    
    
    Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
    In either case, please report this assertion by filing a bug on GitHub:
      https://github.com/flutter/flutter/issues/new?template=2_bug.md
    
    The relevant error-causing widget was: 
      GetMaterialApp-[GlobalKey#5e03f] file:///C:/Users/hazar/AndroidStudioProjects/flutter_getx_the_moviedb/lib/main.dart:38:27
    When the exception was thrown, this was the stack: 
    #2      NavigatorState._debugCheckDuplicatedPageKeys.<anonymous closure> (package:flutter/src/widgets/navigator.dart:3619:18)
    #3      NavigatorState._debugCheckDuplicatedPageKeys (package:flutter/src/widgets/navigator.dart:3624:6)
    #4      NavigatorState._updatePages.<anonymous closure> (package:flutter/src/widgets/navigator.dart:3659:7)
    #5      NavigatorState._updatePages (package:flutter/src/widgets/navigator.dart:3662:6)
    #6      NavigatorState.didUpdateWidget (package:flutter/src/widgets/navigator.dart:3606:7)

我明白了。问题是 GetMaterialApp.router。当您选择使用这种类型的 MaterialApp 时,您必须手动创建 GetDelegate。那是因为,我可以使用 Get.rootDelegate.toNamed() 方法。但我认为这种方式更昂贵,更复杂。所以,我必须改变 3 个不同的东西才能让它工作:

1- 更改 GetMaterialApp.router => GetMaterialApp。然后添加 initialRoute.

main.dart:

import 'package:device_preview/device_preview.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';

import '../../routes/index.dart';
import '../../util/index.dart';

Future<void> initServices() async {
  debugPrint('Starting GetX Services...');
  await GetStorage.init();
  await Get.putAsync(() => GlobalVariablesService().init());
  debugPrint('All GetX Services Started...');
}

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await initServices();

  runApp(
    DevicePreview(
      enabled: false,
      builder: (BuildContext context) => const MovieApp(),
    ),
  );
}

class MovieApp extends StatelessWidget {
  const MovieApp({
    Key? key,
  }) : super(key: key);

  static GlobalKey movieAppKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      key: movieAppKey,
      debugShowCheckedModeBanner: false,
      title: 'Flutter The Movie DB',
      translations: GetTranslations(),
      locale: Get.deviceLocale,
      fallbackLocale: GetTranslations.fallbackLocale,
      theme: Style.lightTheme,
      darkTheme: Style.darkTheme,
      themeMode: ThemeMode.system,
      defaultTransition: Transition.cupertino,
      getPages: AppPages.routes,
      initialRoute: AppRoutes.START,
      enableLog: true,
      //logWriterCallback: (String text, {bool isError = false}) {}
      navigatorObservers: <NavigatorObserver>[
        GetObserver(),
      ],
    );
  }
}

2- 把AppPages.routes改成这样:

app_pages.dart:

import 'package:get/get.dart';

import '../../bindings/index.dart';
import '../../routes/index.dart';
import '../../ui/screens/index.dart';

class AppPages {
  static final List<GetPage<dynamic>> routes = <GetPage<dynamic>>[
    GetPage<StartScreen>(
      name: AppRoutes.START,
      page: () => const StartScreen(),
      binding: StartBinding(),
      preventDuplicates: true,
    ),
    GetPage<HomeMovieScreen>(
      name: AppRoutes.HOME_MOVIE,
      page: () => const HomeMovieScreen(),
      transition: Transition.cupertino,
      binding: HomeMovieBinding(),
    ),
    GetPage<HomeTvScreen>(
      name: AppRoutes.HOME_TV,
      page: () => const HomeTvScreen(),
      transition: Transition.cupertino,
      binding: HomeTvBinding(),
    ),
    GetPage<DetailPage>(
      name: AppRoutes.DETAIL,
      page: () => const DetailPage(),
      transition: Transition.cupertino,
      binding: DetailPageBinding(),
    ),
  ];
}

3- 最后,更改 Get.rootDelegate.toNamed() => Get.toNamed()

现在,这有效! :

Get.toNamed(
  AppRoutes.DETAIL,
  arguments: <String, dynamic>{
    'movie': movieWrapper.results?[index],
    'isMovie': true,
  },
);