
到目前为止,你已经掌握了:
接下来,我们进入 多页面 App 架构:
DefaultTabController(
length: 3, // 标签数量
child: Scaffold(
appBar: AppBar(
title: Text('TabBar 示例'),
bottom: TabBar(
tabs: [
Tab(text: '首页'),
Tab(text: '消息'),
Tab(text: '我的'),
],
),
),
body: TabBarView(
children: [
Center(child: Text('首页内容')),
Center(child: Text('消息内容')),
Center(child: Text('我的内容')),
],
),
),
);
📌 关键点:
DefaultTabController → 管理 Tab 状态TabBar → 标签TabBarView → 内容页与标签对应TabBar(
labelColor: Colors.blue,
unselectedLabelColor: Colors.grey,
indicatorColor: Colors.blue,
indicatorWeight: 3,
tabs: [
Tab(icon: Icon(Icons.home), text: '首页'),
Tab(icon: Icon(Icons.message), text: '消息'),
Tab(icon: Icon(Icons.person), text: '我的'),
],
)
📌 可以自定义:
class BottomNavPage extends StatefulWidget {
@override
_BottomNavPageState createState() => _BottomNavPageState();
}
class _BottomNavPageState extends State<BottomNavPage> {
int _currentIndex = 0;
final List<Widget> _pages = [
Center(child: Text('首页')),
Center(child: Text('消息')),
Center(child: Text('我的')),
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: _pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (index) {
setState(() {
_currentIndex = index;
});
},
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'),
BottomNavigationBarItem(icon: Icon(Icons.message), label: '消息'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: '我的'),
],
),
);
}
}
📌 功能解析:
_currentIndex → 当前页面索引setState 切换页面BottomNavigationBarItem → 图标 + 文本在 BottomNavigationBar 多页面切换中,如果每个页面都是 StatefulWidget,默认会被重新创建。 解决办法:用 IndexedStack 保持页面状态:
body: IndexedStack(
index: _currentIndex,
children: _pages,
),
📌 切换页面不会重建 widget → 页面状态保持
组件 | 适用场景 | 特点 |
|---|---|---|
TabBar | 顶部标签页 | 通常配合 AppBar / TabBarView |
BottomNavigationBar | 底部导航 | 页面多且切换,保持状态建议用 IndexedStack |
📌 结合使用也很常见:
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int _currentIndex = 0;
final List<Widget> _pages = [
DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
title: Text('首页'),
bottom: TabBar(
tabs: [Tab(text: '推荐'), Tab(text: '最新')],
),
),
body: TabBarView(
children: [
Center(child: Text('推荐内容')),
Center(child: Text('最新内容')),
],
),
),
),
Center(child: Text('消息页')),
Center(child: Text('我的页')),
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: IndexedStack(
index: _currentIndex,
children: _pages,
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (index) {
setState(() {
_currentIndex = index;
});
},
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'),
BottomNavigationBarItem(icon: Icon(Icons.message), label: '消息'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: '我的'),
],
),
);
}
}
📌 功能总结:
❌ BottomNavigationBar 切换时页面被重建 → 状态丢失 ❌ TabBar 未用 DefaultTabController → 无法切换 ❌ body / TabBarView 内容与 tabs 数量不匹配 → 报错 ❌ 使用 StatefulWidget 嵌套时未注意 key → 状态错乱
你已经学会:
📌 到这里为止:
你的 Flutter App 已经具备完整的多页面框架能力 ✅
TabBar 顶部切分类 BottomNavigationBar 底部切模块 IndexedStack 保持页面状态 多页面 App 架构完成
《Flutter 零基础入门(四十一):Flutter 主题与自定义样式 —— App 美化必学》
下一篇我们将学习:
🚀 让你的 App 不再“丑丑的”