簡單的 TabBar
可使用 DefaultTabController
實現,若要完全控制 TabBar
,則可使用進階的 TabController
。
Flutter
- Android 與 iOS 都成功使用
TabController
實現TabBar
TabController
import 'package:flutter/material.dart';
class Home extends StatefulWidget {
const Home({super.key});
State<Home> createState() => _Home();
}
class _Home extends State<Home> with SingleTickerProviderStateMixin {
late TabController _tabController;
void initState() {
super.initState();
_tabController = TabController(
length: 3,
vsync: this,
);
_tabController.addListener(
() async {
if (_tabController.indexIsChanging) {
switch (_tabController.index) {
case 0:
print('Car Tab');
break;
case 1:
print('Train Tab');
break;
case 2:
print('Bike Tab');
break;
}
}
},
);
}
void dispose() {
_tabController.dispose();
super.dispose();
}
Widget build(BuildContext context) {
var appBar = AppBar(
title: const Text('TabBar with TabController'),
);
var tabBar = TabBar(
controller: _tabController,
tabs: const [
Tab(text: 'Car'),
Tab(text: 'Train'),
Tab(text: 'Bike'),
],
);
var tabBarView = Expanded(
child: TabBarView(
controller: _tabController,
children: const [
Center(
child: Text('Car Tab'),
),
Center(
child: Text('Train Tab'),
),
Center(
child: Text('Bike Tab'),
),
],
),
);
var body = Column(
children: [
tabBar,
tabBarView,
],
);
return Scaffold(
appBar: appBar,
body: body,
);
}
}
Line 10
class _Home extends State<Home> with SingleTickerProviderStateMixin {
}
SingleTickerProviderStateMixin
:要使用 TabController 時,則該 page 必須使用SingleTickerProviderStateMixin
mixin
Line 11
late TabController _tabController;
late
:因為稍後會在initState()
建立_tabController
,故宣告成late
避免 Dart compiler 檢查
Line 13
void initState() {
super.initState();
_tabController = TabController(
length: 3,
vsync: this,
);
}
_tabController
:在initSate()
內建立TabController
length
:設定 Tab 個數vsync
:可防止動畫在畫面不可見的時候進行無意義的更新,節省 CPU 和電池消耗。此處的this
就是目前的 page
Line 21
_tabController.addListener(
() async {
if (_tabController.indexIsChanging) {
switch (_tabController.index) {
case 0:
print('Car Tab');
break;
case 1:
print('Train Tab');
break;
case 2:
print('Bike Tab');
break;
}
}
},
);
- 當 Tab 被點擊時所觸發的 event
_tabController.indexIsChanging
:是否不同的 Tab 被點擊_tabController.index
:目前所點擊的 Tab
Line 52
var tabBar = TabBar(
controller: _tabController,
tabs: const [
Tab(text: 'Car'),
Tab(text: 'Train'),
Tab(text: 'Bike'),
],
);
TabBar
:建立TabBar
controller
:設定自訂的TabController
Line 61
var tabBarView = Expanded(
child: TabBarView(
controller: _tabController,
children: const [
Center(
child: Text('Car Tab'),
),
Center(
child: Text('Train Tab'),
),
Center(
child: Text('Bike Tab'),
),
],
),
);
TabBarView
:建立TabBarView
controller
:設定自訂的TabController
Line 40
void dispose() {
_tabController.dispose();
super.dispose();
}
- 在
dispose()
釋放自訂的TabConrtroller
Conclusion
- 若要使用自訂的
TabController
,則TabBar
與TabBarView
都必須指定TabController
,且必須在dispose()
加以釋放