Flutter Bottom Navigation Bar标题重复问题求助
Flutter底部导航栏标题重复问题解决
问题情况
开发Flutter底部导航栏时出现标题重复问题,点击Menu按钮会新增标题栏,其余功能正常。效果如图:
相关代码:
class _HomePageState extends State<HomePage> { int _opcaoselecionada = 0; final List<Widget> _telas = [ Menu(), HomePage(), Graficos(), ]; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('bem vindo') ), body: _telas[_opcaoselecionada], bottomNavigationBar: BottomNavigationBar( type: BottomNavigationBarType.fixed, currentIndex: _opcaoselecionada, onTap: onTabTapped, items: [ BottomNavigationBarItem( icon: Icon(Icons.add), label: "Menu", ), BottomNavigationBarItem( icon: Icon(Icons.house_outlined), label: "inicial", ), BottomNavigationBarItem( icon: Icon(Icons.auto_graph), label: "graficos", ) ], ), ); } void onTabTapped(int index) { setState(() { _opcaoselecionada = index; }); } }
问题原因
代码里的_telas列表直接实例化了HomePage(),而HomePage本身就是一个包含Scaffold和AppBar的完整页面。当底部导航切换到这个页面时,会形成嵌套Scaffold——外层HomePage的AppBar加上内层HomePage的AppBar,导致标题重复。如果Menu页面也自带Scaffold和AppBar,点击Menu时也会新增标题栏。
解决方案
方案一:统一管理导航与标题(推荐)
将各个页面的内容抽离出来,去掉各自的Scaffold和AppBar,由外层HomePage统一管理AppBar和底部导航栏,还可根据当前选中页面动态切换标题。
修改后代码示例:
class _HomePageState extends State<HomePage> { int _opcaoselecionada = 0; // 存放仅包含内容的组件,无Scaffold和AppBar final List<Widget> _telas = [ MenuContent(), HomeContent(), GraficosContent(), ]; // 对应各页面的标题 final List<String> _pageTitles = [ "菜单", "bem vindo", "图表" ]; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(_pageTitles[_opcaoselecionada]), // 动态切换标题 ), body: _telas[_opcaoselecionada], bottomNavigationBar: BottomNavigationBar( type: BottomNavigationBarType.fixed, currentIndex: _opcaoselecionada, onTap: onTabTapped, items: const [ BottomNavigationBarItem( icon: Icon(Icons.add), label: "Menu", ), BottomNavigationBarItem( icon: Icon(Icons.house_outlined), label: "inicial", ), BottomNavigationBarItem( icon: Icon(Icons.auto_graph), label: "graficos", ) ], ), ); } void onTabTapped(int index) { setState(() { _opcaoselecionada = index; }); } } // 示例:抽离的首页内容组件 class HomeContent extends StatelessWidget { const HomeContent({super.key}); @override Widget build(BuildContext context) { return Center( child: Text("首页内容区域"), ); } } // 同理实现MenuContent和GraficosContent
方案二:移除外层AppBar
如果需要保留各页面的独立Scaffold,可以去掉外层HomePage的AppBar,由各个子页面自行管理AppBar和标题。但这种方式不推荐,因为底部导航栏需要统一在外层管理,否则每个页面都要重复写底部导航代码。
修改后外层代码示例:
class _HomePageState extends State<HomePage> { int _opcaoselecionada = 0; final List<Widget> _telas = [ Menu(), HomePageWithScaffold(), Graficos(), ]; @override Widget build(BuildContext context) { return Scaffold( // 移除外层AppBar body: _telas[_opcaoselecionada], bottomNavigationBar: BottomNavigationBar( type: BottomNavigationBarType.fixed, currentIndex: _opcaoselecionada, onTap: onTabTapped, items: const [ BottomNavigationBarItem( icon: Icon(Icons.add), label: "Menu", ), BottomNavigationBarItem( icon: Icon(Icons.house_outlined), label: "inicial", ), BottomNavigationBarItem( icon: Icon(Icons.auto_graph), label: "graficos", ) ], ), ); } void onTabTapped(int index) { setState(() { _opcaoselecionada = index; }); } } // 独立的带Scaffold的首页 class HomePageWithScaffold extends StatelessWidget { const HomePageWithScaffold({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("bem vindo")), body: Center(child: Text("首页内容")), ); } }
内容的提问来源于stack exchange,提问作者duda
相关产品推荐
相关产品推荐

