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

Flutter bottomNavigationBar页面切换引发应用崩溃问题

崩溃原因

你遇到的是无限递归嵌套导致的栈溢出崩溃,问题就出在screens数组的配置上:

  • 你在HomeScreen对应的State里,把HomeScreen()本身放到了tab页面数组的第一个位置
  • 每次HomeScreen构建时都会创建新的HomeScreen实例,新实例又会在自己的screens数组里再创建一层HomeScreen,无限循环嵌套会瞬间占满调用栈,直接触发应用崩溃,和你把导航写在哪个文件里没有关系。
修复方法

核心逻辑是:承载BottomNavigationBar的HomeScreen只做tab切换的容器,不要把容器自身放到待切换的tab页面列表里,把第一个tab的实际首页内容抽成独立组件即可。
修复后的完整代码参考:

// 底部导航容器组件,不要将该组件放入tab切换的页面列表中
class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  // 替换第一个元素为实际的首页内容组件,禁止写HomeScreen()
  final screens = [
    const HomeTabPage(), // 替换为你自己的首页内容组件,命名可自定义
    const ProfilScreen(),
    const ConversationsScreen(),
  ];

  int currentIndex = 0;


  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: screens[currentIndex],
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: currentIndex,
        backgroundColor: Colors.black26,
        type: BottomNavigationBarType.fixed,
        selectedItemColor: Colors.purpleAccent,
        iconSize: 30,
        showSelectedLabels: false,
        showUnselectedLabels: false,
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: "Home"),
          BottomNavigationBarItem(
              icon: Icon(Icons.mail_outline), label: "Message"),
          BottomNavigationBarItem(icon: Icon(Icons.person), label: "Profil"),
        ],
        onTap: (index) {
          setState(() {
            currentIndex = index;
          });
        },
      ),
    );
  }
}

// 第一个tab对应的首页实际内容,单独抽离
class HomeTabPage extends StatelessWidget {
  const HomeTabPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // 这里写你原本要在首页展示的所有内容,包括你之前注释掉的AppBar也可以放在这里
    return Scaffold(
      appBar: AppBar(
        title: Text("首页"),
        centerTitle: true,
      ),
      body: Center(
        child: Text("这是首页内容区"),
      ),
    );
  }
}
补充说明
  • 你不需要把底部导航逻辑写到main.dart里,抽离在HomeScreen中完全可以正常运行,不会影响注册页到首页的跳转逻辑。
  • 如果需要保持各个tab页的状态不被切换重置,可以给每个tab页面加AutomaticKeepAliveClientMixin,或者用IndexedStack包裹screens数组,替换body的写法为body: IndexedStack(index: currentIndex, children: screens,)即可。

内容的提问来源于stack exchange,提问作者Célia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 16:45:39