Flutter:如何通过滑动底部导航栏切换对应页面?
问题分析与解决方案
你的代码存在两处关键问题:一是误用了DefaultTabController却自行维护_screen状态,DefaultTabController本身会自动管理Tab的选中索引,不需要额外状态;二是TabBarView里的switch仅处理了case 0,导致无论滑动到哪个Tab都只返回同一个文本页面。
下面提供几种可行的实现方式,按需选择:
方式一:直接使用页面列表(最简洁)
适合页面结构规整、无需复杂初始化逻辑的场景,通过创建与tabNames顺序一一对应的页面组件列表,直接在TabBarView中返回对应页面,代码清爽易维护。
修改后完整代码
class MyHomePage extends StatefulWidget { const MyHomePage({super.key}); @override State<MyHomePage> createState() => _MyHomePageState(); } const List<String> tabNames = <String>[ 'Reports', 'Reminders', 'Savings', 'Subscription', 'BudgetPlanner', ]; // 定义各个独立页面组件 class ReportsPage extends StatelessWidget { const ReportsPage({super.key}); @override Widget build(BuildContext context) { return const Center(child: Text('Reports Page')); } } class RemindersPage extends StatelessWidget { const RemindersPage({super.key}); @override Widget build(BuildContext context) { return const Center(child: Text('Reminders Page')); } } class SavingsPage extends StatelessWidget { const SavingsPage({super.key}); @override Widget build(BuildContext context) { return const Center(child: Text('Savings Page')); } } class SubscriptionPage extends StatelessWidget { const SubscriptionPage({super.key}); @override Widget build(BuildContext context) { return const Center(child: Text('Subscription Page')); } } class BudgetPlannerPage extends StatelessWidget { const BudgetPlannerPage({super.key}); @override Widget build(BuildContext context) { return const Center(child: Text('BudgetPlanner Page')); } } class _MyHomePageState extends State<MyHomePage> { // 页面列表与tabNames顺序严格对应 final List<Widget> _pages = const [ ReportsPage(), RemindersPage(), SavingsPage(), SubscriptionPage(), BudgetPlannerPage(), ]; @override Widget build(BuildContext context) { return DefaultTabController( length: tabNames.length, child: Scaffold( appBar: const AppBar(title: Text('Navigation example')), body: TabBarView(children: _pages), bottomNavigationBar: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Material( color: Theme.of(context).primaryColor, child: const TabBar( isScrollable: true, tabs: [ Tab(text: 'REPORTS'), Tab(text: 'REMINDERS'), Tab(text: 'SAVINGS'), Tab(text: 'SUBSCRIPTION'), Tab(text: 'BUDGETPLANNER'), ], ), ), ], ), ), ); } }
方式二:使用switch语句(适合复杂页面场景)
如果每个页面需要单独初始化逻辑、传递不同参数,用switch根据索引返回对应页面会更灵活。
修改TabBarView部分代码
body: TabBarView( children: List.generate(tabNames.length, (index) { switch(index) { case 0: return const ReportsPage(); case 1: return const RemindersPage(); case 2: return const SavingsPage(); case 3: return const SubscriptionPage(); case 4: return const BudgetPlannerPage(); default: return const Center(child: Text('Unknown Page')); } }), ),
方式三:使用映射表(适合大量页面场景)
当页面数量较多时,用Map映射索引与页面,维护起来更便捷:
实现代码
// 定义页面映射表 final Map<int, Widget> _pageMap = { 0: const ReportsPage(), 1: const RemindersPage(), 2: const SavingsPage(), 3: const SubscriptionPage(), 4: const BudgetPlannerPage(), }; // TabBarView部分 body: TabBarView( children: List.generate(tabNames.length, (index) => _pageMap[index] ?? const Center(child: Text('Unknown Page')) ), ),
内容的提问来源于stack exchange,提问作者User G Amsterdam
相关产品推荐
相关产品推荐

