如何从独立文件中渲染Flutter底部导航栏Widget?
如何将Flutter底部导航栏抽成独立可复用Widget(遵循DRY原则)
当然可以把重复的底部导航栏封装成独立Widget,彻底消除代码冗余,下面是具体实现步骤:
1. 新建独立的导航栏Widget文件
创建custom_bottom_navbar.dart文件,把导航栏代码封装成一个可配置的StatelessWidget,将动态参数(当前选中索引、点击回调)暴露给外部:
import 'package:flutter/material.dart'; class CustomBottomNavbar extends StatelessWidget { final int currentIndex; final void Function(int) onItemTapped; const CustomBottomNavbar({ super.key, required this.currentIndex, required this.onItemTapped, }); @override Widget build(BuildContext context) { return BottomNavigationBar( items: const <BottomNavigationBarItem>[ BottomNavigationBarItem( icon: Icon(Icons.home), label: 'Home', backgroundColor: Colors.green, ), BottomNavigationBarItem( icon: Icon(Icons.search), label: 'Search', backgroundColor: Colors.yellow, ), BottomNavigationBarItem( icon: Icon(Icons.person), label: 'Profile', backgroundColor: Colors.blue, ), ], type: BottomNavigationBarType.shifting, currentIndex: currentIndex, selectedItemColor: Colors.black, iconSize: 40, onTap: onItemTapped, elevation: 5, ); } }
2. 在页面中复用该Widget
修改你的Home页面(以及其他需要底部导航的页面),导入自定义导航栏,替换原有的硬编码导航栏:
import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; // 导入自定义导航栏文件 import 'custom_bottom_navbar.dart'; class Home extends StatefulWidget { const Home({Key? key}) : super(key: key); @override _HomeState createState() => _HomeState(); } class _HomeState extends State<Home> { int _selectedIndex = 0; final List<String> pages = ['home', 'search', 'profile']; void _onItemTapped(int index) { String page = pages[index]; context.go('/$page'); // 更新选中索引,保持导航栏状态同步 setState(() => _selectedIndex = index); } @override Widget build(BuildContext context) { return Scaffold( body: const SafeArea( child: Center( child: Text("Home page", style: TextStyle(fontSize: 50)), ), ), // 直接复用自定义导航栏 bottomNavigationBar: CustomBottomNavbar( currentIndex: _selectedIndex, onItemTapped: _onItemTapped, ), ); } }
3. 进阶优化:统一管理导航状态(可选)
如果不想每个页面都维护_selectedIndex,可以利用GoRouter的当前路由自动判断选中项,进一步简化代码:
修改custom_bottom_navbar.dart,添加路由匹配逻辑:
import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; class CustomBottomNavbar extends StatelessWidget { final void Function(int) onItemTapped; const CustomBottomNavbar({ super.key, required this.onItemTapped, }); // 根据当前路由自动获取选中索引 int _getCurrentIndex(BuildContext context) { final location = GoRouterState.of(context).location; if (location.contains('/search')) return 1; if (location.contains('/profile')) return 2; return 0; } @override Widget build(BuildContext context) { return BottomNavigationBar( // 省略其他固定配置... currentIndex: _getCurrentIndex(context), onTap: onItemTapped, ); } }
这样每个页面就不需要维护_selectedIndex状态了,完全遵循DRY原则。
内容的提问来源于stack exchange,提问作者Duddy67
相关产品推荐
相关产品推荐

