Flutter GoRouter未导航到选择的路由。

huangapple go评论72阅读模式
英文:

Flutter GoRouter not navigating to selected rouye

问题

路由配置(goRouterProvider.dart)中返回了正确的路径,但在从主屏幕选择类别后未导航到所需的CategoriesFeedScreen。以下是三个涉及此导航和问题的代码文件。请帮助解决此问题,我已经自己尝试了三周,但没有成功。谢谢

CategoriesFeedScreen类:

CategoriesFeedScreen类是一个HookConsumerWidget。它接收参数name,用于显示特定类别的产品列表。

CategoryWidget类:

CategoryWidget类是一个HookConsumerWidget,它根据提供的索引i显示特定类别,并在用户点击时导航至相关类别页面。

main.dart文件:

在main.dart文件中,应用程序构建使用了goRouterProvider和其他provider来处理路由和数据。在函数build中,观察了goRouterProvider以获取路由配置。在useEffect中,执行了一些数据获取和应用程序初始化操作。

请注意,这是Flutter和goRouter的代码,它用于路由管理和屏幕导航。您可能需要检查CategoriesFeedScreen和CategoryWidget以及路由配置是否正确。

英文:

Router config returns the correct path upon selecting a category from the homescreen but not navigating to the desired CategoriesFeedScreen. Here are the 3 code files guigind this navigation and the issues. Please assist as I have tried to resolve this issue for 3 weeks now on my own and no luck. Thanks

Router config (goRouterProvider.dart)

final GlobalKey<NavigatorState> _rootNavigator = GlobalKey(debugLabel: 'root');
final GlobalKey<NavigatorState> _shellNavigator =
    GlobalKey(debugLabel: 'shell');

final goRouterProvider = Provider<GoRouter>(
  (ref) {
    bool isDuplicate = false;
    final notifier = ref.read(goRouterNotifierProvider);

    return GoRouter(
      navigatorKey: _rootNavigator,
      debugLogDiagnostics: true,
      initialLocation: '/',
      refreshListenable: notifier,
      redirect: (context, state) {
        final isLoggedIn = notifier.value;
        final isGoingToLogin = state.subloc == '/auth-screen';

        if (!isLoggedIn && !isGoingToLogin && !isDuplicate) {
          isDuplicate = true;
          return '/auth-screen';
        }
        if (isLoggedIn && isGoingToLogin && !isDuplicate) {
          isDuplicate = true;
          return '/';
        }

        if (isDuplicate) {
          isDuplicate = false;
        }

        return null;
      },
      routes: [
        GoRoute(
          path: '/landing',
          name: 'landing',
          builder: (context, state) => LandingScreen(key: state.pageKey),
        ),
        GoRoute(
          path: '/auth-screen',
          name: 'auth-screen',
          builder: (context, state) => AuthScreen(key: state.pageKey),
        ),
        ShellRoute(
          navigatorKey: _shellNavigator,
          builder: (context, state, child) =>
              BottomNavScreen(key: state.pageKey, child: child),
          routes: [
            GoRoute(
              path: '/',
              name: RouteConstants.homeRouteName,
              pageBuilder: (context, state) {
                return NoTransitionPage(
                  child: HomeScreen(
                    key: state.pageKey,
                  ),
                );
              },
              routes: [
              
                GoRoute(
                  parentNavigatorKey: _shellNavigator,
                  path: 'categories/:name',
                  name: RouteConstants.categoriesRouteName,
                  pageBuilder: (context, state) {
                    return NoTransitionPage(
                      child: CategoriesFeedScreen(
                        name: state.params['name']!,
                        key: state.pageKey,
                      ),
                    );
                  },
                ),
                GoRoute(
                  parentNavigatorKey: _shellNavigator,
                  path: 'brands/:id',
                  name: RouteConstants.brandsRoutename,
                  pageBuilder: (context, state) {
                    return NoTransitionPage(
                      child: BrandsNavRail(
                        id: int.parse(state.params['id']!),
                        key: state.pageKey,
                      ),
                    );
                  },
                ),
                GoRoute(
                  parentNavigatorKey: _shellNavigator,
                  path: 'popular-products/:id',
                  name: RouteConstants.popularProductsRouteName,
                  pageBuilder: (context, state) {
                    return NoTransitionPage(
                      child: PopularProducts(
                        id: state.params['id']!,
                        key: state.pageKey,
                      ),
                    );
                  },
                )
              ],
            ),
            GoRoute(
              path: '/feeds',
              name: RouteConstants.feedsRouteName,
              pageBuilder: (context, state) {
                return NoTransitionPage(
                  child: FeedsScreen(
                    key: state.pageKey,
                  ),
                );
              },
              routes: [
                GoRoute(
                  parentNavigatorKey: _shellNavigator,
                  path: 'details/:id',
                  name: RouteConstants.detailsRouteName,
                  pageBuilder: (context, state) {
                    // final id = state.params['id'].toString();
                    return NoTransitionPage(
                      child: ProductDetailsScreen(
                        id: state.params['id']!,
                        key: state.pageKey,
                      ),
                    );
                  },
                )
              ],
            ),
            GoRoute(
              path: '/cart',
              name: RouteConstants.cartRouteName,
              pageBuilder: (context, state) {
                return NoTransitionPage(
                  child: CartScreen(
                    key: state.pageKey,
                  ),
                );
              },
            ),
            GoRoute(
              path: '/account',
              name: RouteConstants.accountRouteName,
              pageBuilder: (context, state) {
                return NoTransitionPage(
                  child: AccountScreen(
                    key: state.pageKey,
                  ),
                );
              },
            )
          ],
        )
      ],
      errorBuilder: (context, state) => RouteErrorScreen(
        errorMsg: state.error.toString(),
        key: state.pageKey,
      ),
    );
  },
);

CategoriesFeedScreen:

class CategoriesFeedScreen extends HookConsumerWidget {
  final String name;
  const CategoriesFeedScreen({Key? key, required this.name}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final categoryName = ref.watch(categoryProvider);
    final productList = ref.watch(productProvider.notifier);

    final catProductList = productList.findByCatName(
      categoryName.toString(),
    );

    return Scaffold(
      appBar: AppBar(
        title: Text(name),
      ),
      body: GridView.builder(
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2,
          crossAxisSpacing: 10,
          childAspectRatio: 2 / 3,
          mainAxisSpacing: 10,
        ),
        itemCount: catProductList.length,
        itemBuilder: (context, i) {
          return FeedsProduct(
            id: catProductList[i].id,
          );
        },
      ),
    );
  }
}

CategoryWidget:

class CategoryWidget extends HookConsumerWidget {
  CategoryWidget({Key? key, required this.i}) : super(key: key);
  final int i;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final categoryLabel = ref.watch(categoryProvider);

    return InkWell(
        onTap: () {
         
          return context.goNamed(
            RouteConstants.categoriesRouteName,
            params: {'name': categoryLabel[i].name.toLowerCase()},
          );
        },
        child: Container(

main.dart:

Widget build(BuildContext context, WidgetRef ref) {
    final router = ref.watch(goRouterProvider);
    final categoryLabels = ref.watch(categoryProvider.notifier);
    final productList = ref.watch(productProvider.notifier);
    // final themeStatus = ref.watch(
    //     themeProvider.notifier); // used to switch between dark and light modes
    useEffect(() {
      resetNewLaunch();
      productList.fetchProducts();
      categoryLabels.getCategoryLabels();

      return;
    }, const []);
    return ref.watch(authStateChangeProvider).when(
          data: (data) => ResponsiveSizer(
            builder: (context, orientation, screenType) {
              return MaterialApp.router(
                debugShowCheckedModeBanner: false,
                builder: BotToastInit(), // call BotToastInit
                // navigatorObservers: [BotToastNavigatorObserver()],
                // theme: AppTheme.myTheme(themeStatus.getTheme(), context),
                darkTheme: ThemeData.dark(),
                routeInformationParser: router.routeInformationParser,
                routeInformationProvider: router.routeInformationProvider,
                routerDelegate: router.routerDelegate,
              );
            },
          ),
          error: (error, stackTrace) => ErrorText(error: error.toString()),
          loading: () => const Loader(),
        );
  }
}

I am running the latest flutter version and goRouter package. Thanks a bunch for your help

答案1

得分: 1

已解决非导航问题。在routerConfig文件(goRouterProvider)中将子路由的parentNavigatorKey从_shellNavigator更改为_rootNavigator,这样可以使新屏幕显示在bottomwnavigator外部。尽管正确的参数和路径已注册,但子路由仍然拒绝在bottomNav选项卡内打开。

英文:

Fixed the non-navigation issue. Changed the parentNavigatorKey in the sub-routes of the routerConfig file (goRouterProvider) from _shellNavigator to _rootNavigator which allows the new screens to display outside of the bottomwnavigator shell. The sub-routes simply refused to open inside of the bottomNav tabs even though the correct params and paths were being registered.
.

huangapple
  • 本文由 发表于 2023年2月16日 11:10:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/75467482.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定