英文:
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.
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论