Flutter自定义BottomNavigationBar点击后页面不更新问题求助
问题原因及解决方案
问题根源
- Home是无状态组件:你用
StatelessWidget定义的Home组件,全局变量index改变时,不会触发它的build方法重新执行,所以Scaffold的body内容不会更新。 - 状态管理混乱:页面索引
index作为全局变量存在,底部导航的选中状态selectPage则在自身State类中,两者状态更新没有联动机制,且全局变量的变更无法驱动无状态组件重建。
修复方案及代码示例
把Home改为有状态组件,将页面索引移到Home的状态中,同时给自定义底部导航添加回调函数,让点击事件能通知Home更新状态:
class Home extends StatefulWidget { const Home({Key? key}) : super(key: key); @override State<Home> createState() => _HomeState(); } class _HomeState extends State<Home> { int index = 0; final List<Widget> pages = [ const HomeScreen(), const FolderScreen(), ]; @override Widget build(BuildContext context) { return Scaffold( body: pages[index], bottomNavigationBar: CustomBottomNavigationBar( currentIndex: index, onTap: (newIndex) { setState(() { index = newIndex; }); }, ), ); } } enum Pages { home, folder, } class CustomBottomNavigationBar extends StatefulWidget { final int currentIndex; final Function(int) onTap; const CustomBottomNavigationBar({ Key? key, required this.currentIndex, required this.onTap, }) : super(key: key); @override State<CustomBottomNavigationBar> createState() => _CustomBottomNavigationBarState(); } class _CustomBottomNavigationBarState extends State<CustomBottomNavigationBar> { Pages get selectPage => widget.currentIndex == 0 ? Pages.home : Pages.folder; @override Widget build(BuildContext context) { Size size = MediaQuery.of(context).size; return SizedBox( width: size.width, height: 80.0, child: Stack( children: [ CustomPaint( size: Size(size.width, 80.0), painter: BNBCustomPainter(), ), Center( heightFactor: 0.71, child: Transform.scale( scale: 1.25, child: FloatingActionButton( onPressed: () {}, backgroundColor: Colors.blueAccent, elevation: 0.1, child: const Icon( Icons.add, size: 40, ), ), ), ), SizedBox( width: size.width, height: 80.0, child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ IconButton( onPressed: () => widget.onTap(0), icon: Icon( Icons.home, color: selectPage == Pages.home ? kActiveBottomNavigationButtonColor : kInactiveBottomNavigationButtonColor, size: 35.0, ), ), SizedBox(width: size.width * 0.20), IconButton( onPressed: () => widget.onTap(1), icon: Icon( Icons.folder, color: selectPage == Pages.folder ? kActiveBottomNavigationButtonColor : kInactiveBottomNavigationButtonColor, size: 35.0, ), ), ], ), ), ], ), ); } }
关键改动说明
- 将
Home从StatelessWidget改为StatefulWidget,把页面索引index纳入其状态管理,调用setState即可触发组件重建,切换body内容。 - 给
CustomBottomNavigationBar新增currentIndex和onTap参数,让底部导航的点击事件能传递给Home组件,驱动状态更新。 - 移除全局变量
index,底部导航的选中状态通过currentIndex计算得出,保证状态统一且可控。
内容的提问来源于stack exchange,提问作者Lukas
相关产品推荐
相关产品推荐

