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

使用persistent_bottom_nav_bar的NavBarStyle.style15报断言错误如何解决

问题原因

从报错日志可以直接定位到核心问题:persistent_bottom_nav_bar 包中,NavBarStyle.style15 属于15-18号的特殊样式组,这类带中间突出按钮的样式仅支持3个或5个底部导航项,你当前代码中仅配置了2个导航项,触发了框架的断言校验。
另外你的代码还存在一个逻辑问题:bottomNav 组件的 _buildScreens 方法返回的页面包含了嵌套 bottomNav 的 MyHomePage,会导致组件循环渲染的嵌套问题,也需要同步修复。

修复方案

方案1:保留style15样式(符合你的需求)

需要将底部导航项调整为3个/5个,同时同步对应页面数量,并且修改循环嵌套的逻辑:

第一步:修改bottomNav.dart的导航项和页面配置

// 先新增独立的tab页面,不要包含bottomNav组件
class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("首页")),
      body: Center(child: Text("首页内容")),
    );
  }
}

class ChatScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("聊天")),
      body: Center(child: Text("聊天内容")),
    );
  }
}

class PublishScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("发布")),
      body: Center(child: Text("发布内容")),
    );
  }
}

class bottomNav extends StatelessWidget {
  PersistentTabController _controller = PersistentTabController(initialIndex: 0);
  
  @override
  Widget build(BuildContext context) {
    return PersistentTabView(
      context,
      controller: _controller,
      screens: _buildScreens(),
      items: _navBarsItems(),
      confineInSafeArea: true,
      backgroundColor: Colors.white,
      
      handleAndroidBackButtonPress: true,
      resizeToAvoidBottomInset: true,
      stateManagement: true,
      hideNavigationBarWhenKeyboardShows: true,

      decoration: NavBarDecoration(
        borderRadius: BorderRadius.circular(10.0),
        colorBehindNavBar: Colors.white,
      ),
      popAllScreensOnTapOfSelectedTab: true,
      popActionScreens: PopActionScreensType.all,
      itemAnimationProperties: ItemAnimationProperties(
        duration: Duration(milliseconds: 200),
        curve: Curves.ease,
      ),
      screenTransitionAnimation: ScreenTransitionAnimation(
        animateTabTransition: true,
        curve: Curves.ease,
        duration: Duration(milliseconds: 200),
      ),
      navBarStyle: NavBarStyle.style15,
    );
  }

  // 页面数量和导航项数量保持一致,3个导航项对应3个页面
  List<Widget> _buildScreens(){
    return [
      HomeScreen(),
      PublishScreen(),
      ChatScreen(),
    ];
  }

  // 调整为3个导航项
  List<PersistentBottomNavBarItem> _navBarsItems(){
    return [
      PersistentBottomNavBarItem(
        icon: Icon(Icons.home),
        title: ("Home"),
        activeColorPrimary: Color(0xFF254690),
        inactiveColorPrimary: Color(0xFFD3DAE9),
      ),
      PersistentBottomNavBarItem(
        icon: Icon(Icons.add_circle),
        title: ("Publish"),
        activeColorPrimary: Color(0xFF254690),
        inactiveColorPrimary: Color(0xFFD3DAE9),
      ),
      PersistentBottomNavBarItem(
        icon: Icon(Icons.chat_rounded),
        title: ("Chat"),
        activeColorPrimary: Color(0xFF254690),
        inactiveColorPrimary: Color(0xFFD3DAE9),
      ),
    ];
  }
}

第二步:修改main.dart的入口配置,避免循环嵌套

import 'package:flutter/material.dart';
import 'package:project1_makers/bottomNav.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(primaryColor: Colors.white),
      debugShowCheckedModeBanner: false,
      // 直接把bottomNav作为根页面,不要套MyHomePage
      home: bottomNav(),
    );
  }
}

方案2:保留2个导航项,更换支持的样式

如果你确实只需要2个底部导航,可以把navBarStyle改为支持2个项的样式即可:

// 把style15替换为style1即可,style1-style14大部分都支持2个导航项
navBarStyle: NavBarStyle.style1,

同步也要把_buildScreens的页面数量调整为2个,并且修复循环嵌套的问题。

内容的提问来源于stack exchange,提问作者chunzhi23

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 07:54:03