You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 04:20:28