将 TabBarView 与 BottomNavigationBar 和 StatefulShellRoute(go_router) 一起使用时,setState() 或 markNeedsBuild() 出错

问题描述 投票:0回答:1

我正在使用 StatefulShellRoute(

BottomNavigationBar
) 在其中一个屏幕中构建一个带有
TabBarView
go_router
的 Flutter 应用程序。当我在 TabBarView 中的选项卡之间滑动并在选项卡切换动画完成之前快速切换到不同的底部导航项时,应用程序崩溃并出现以下错误, 在构建期间调用 setState() 或 markNeedsBuild()。

import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; void main() { runApp(const App()); } class App extends StatelessWidget { const App({super.key}); @override Widget build(BuildContext context) => MaterialApp.router(routerConfig: mainRouter); } final _mainKey = GlobalKey<NavigatorState>(); final _dashboardKey = GlobalKey<NavigatorState>(); final _favouritesKey = GlobalKey<NavigatorState>(); final _settingsKey = GlobalKey<NavigatorState>(); final GoRouter mainRouter = GoRouter( initialLocation: '/dashboard', navigatorKey: _mainKey, routes: [ StatefulShellRoute.indexedStack( builder: (context, state, navigationShell) => HomeNavHost(navigationShell: navigationShell), branches: [ StatefulShellBranch( navigatorKey: _dashboardKey, routes: [ GoRoute( path: '/dashboard', pageBuilder: (context, state) => NoTransitionPage(child: Center(child: Text('Dashboard'))), ), ], ), StatefulShellBranch( navigatorKey: _favouritesKey, routes: [ GoRoute( path: '/favourites', pageBuilder: (context, state) => NoTransitionPage(child: FavouritesScreen()), ), ], ), StatefulShellBranch( navigatorKey: _settingsKey, routes: [ GoRoute( path: '/settings', pageBuilder: (context, state) => NoTransitionPage(child: Center(child: Text('Settings'))), ), ], ), ], ) ], ); class HomeNavHost extends StatelessWidget { const HomeNavHost({required this.navigationShell, super.key}); final StatefulNavigationShell navigationShell; @override Widget build(BuildContext context) { return Scaffold( body: navigationShell, bottomNavigationBar: BottomNavigationBar( currentIndex: navigationShell.currentIndex, onTap: (index) => navigationShell.goBranch( index, initialLocation: index == navigationShell.currentIndex, ), items: [ BottomNavigationBarItem( icon: Icon(Icons.dashboard), label: 'Dashboard', ), BottomNavigationBarItem( icon: Icon(Icons.favorite), label: 'Favourites', ), BottomNavigationBarItem( icon: Icon(Icons.settings), label: 'Settings', ), ], ), ); } } class FavouritesScreen extends StatefulWidget { const FavouritesScreen({super.key}); @override State<FavouritesScreen> createState() => _FavouritesScreenState(); } class _FavouritesScreenState extends State<FavouritesScreen> { @override Widget build(BuildContext context) { return DefaultTabController( length: 2, child: Scaffold( appBar: AppBar( title: Text('Favourites'), bottom: TabBar( tabs: [ Tab(text: 'Catergory 1'), Tab(text: 'Catergory 2'), ], ), ), body: TabBarView( children: [ Center(child: Text('Catergory 1')), Center(child: Text('Catergory 2')), ], ), ), ); } }

TabBarView
BottomNavigationBar

一起使用在正常情况下可以无缝工作(即没有

go_router
),并且通过点击顶部的 tabTitle 来切换选项卡也不会出现任何问题。
但是,使用 
StatefulShellRoute
时,在

TabBarView

中的选项卡之间滑动并快速切换到另一个底部导航项会导致错误。 我试过:


使用
AutomaticKeepAliveClientMixin

  • 使用
    WidgetsBinding.instance.addPostFrameCallback
  • SchedulerBinding.instance.addPostFrameCallback
  • 延迟底部栏导航。
    
    
    BottomNavigationBar
TabBarView

之间切换时如何避免此问题?

任何与 
TabBarView
结合管理

BottomNavigationBar

的指导或最佳实践将不胜感激!

    
请重构您的 dart 代码的这一部分:

flutter bottomnavigationview tabbar
1个回答
0
投票

onTap: (index) => navigationShell.goBranch( index, initialLocation: index == navigationShell.currentIndex, ),

至:

onTap: (index) {
  WidgetsBinding.instance.addPostFrameCallback((_) {
    navigationShell.goBranch(
      index,
      initialLocation: index == navigationShell.currentIndex,
    );
  });
},

修改代码后再次测试。

希望对你有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.