Flutter中GNav切换页面因已销毁调用setState导致崩溃问题
问题分析与解决方案
你遇到的崩溃核心原因是:所有页面共用同一个GNav实例,切换页面时旧页面组件被销毁,但GNav的400ms动画仍在运行,动画回调中的setState会在已销毁的组件上下文里执行,触发setState() called after dispose错误。
以下是两种可行的解决办法:
方案一:给每个页面分配独立的GNav实例
避免共用同一个GNav对象,同时在状态更新前判断组件是否还处于挂载状态,防止无效的setState调用。
// 封装GNav创建方法,每次调用返回新实例 Widget _buildGNav() { return SafeArea( child: GNav( haptic: true, duration: const Duration(milliseconds: 400), gap: 8, color: Colors.grey[600], padding: const EdgeInsets.only(left: 20, right: 20, top: 12, bottom: 5), activeColor: Theme.of(context).primaryColor, selectedIndex: _selectedIndex, onTabChange: (index) { // 先确认组件未被销毁,再执行状态更新 if (mounted) { setState(() { _selectedIndex = index; }); } }, tabs: _buttons, ), ); } // 每个页面使用独立的GNav实例 List<Widget> head = [ SearchHeader(bottom: _buildGNav(), body: const HomePage()), SearchHeader(bottom: _buildGNav(), body: const SearchPage()), SelectorHeader( bottom: _buildGNav(), body: const LibraryPage(), tabs: const TabBar(tabs: [Text("Continue"), Text("Favourite"), Text("My")]), length: 3, ), EmptyHeader(bottom: _buildGNav(), body: const SettingsPage()), ];
方案二:将GNav提升到父组件的Scaffold中(更推荐)
底部导航栏属于全局持久化组件,没必要随页面切换重建。把GNav放到父组件的bottomNavigationBar中,让它的生命周期和父组件绑定,从根源上避免动画期间组件被销毁的问题。
// 父组件直接返回包含GNav的Scaffold return Scaffold( bottomNavigationBar: SafeArea( child: GNav( haptic: true, duration: const Duration(milliseconds: 400), gap: 8, color: Colors.grey[600], padding: const EdgeInsets.only(left: 20, right: 20, top: 12, bottom: 5), activeColor: Theme.of(context).primaryColor, selectedIndex: _selectedIndex, onTabChange: (index) { if (mounted) { setState(() { _selectedIndex = index; }); } }, tabs: _buttons, ), ), // 页面内容直接作为Scaffold的body body: head[_selectedIndex], ); // 此时head列表中的Header无需再传递bottom参数 List<Widget> head = [ const SearchHeader(body: HomePage()), const SearchHeader(body: SearchPage()), const SelectorHeader( body: LibraryPage(), tabs: TabBar(tabs: [Text("Continue"), Text("Favourite"), Text("My")]), length: 3, ), const EmptyHeader(body: SettingsPage()), ];
内容的提问来源于stack exchange,提问作者frederik
相关产品推荐
相关产品推荐

