顶部TabLayout的实现
TabBar是作为AppBar的一部分存在。Flutter SDK中提供了两种实现顶部TabLayout的方法,两者效果是一样的,但第二种功能更为丰富。具体为 TabBar + TabBarView
两个weight结合。
话不多说上代码:
方法一:DefaultTabController
使用 DefaultTabController
作为最外层控制器,联调 TabBar + TabBarView
,这种方式简单方便,但致命缺点是拿不到当前选中tab的index。
class FirstPage extends StatefulWidget {
FirstPage({Key key, this.title}) : super(key: key);
final String title;
@override
State<StatefulWidget> createState() => _FirstPageState();
}
/// DefaultTabController (TabBar + TabBarView) 使用 (内部还是TabController实现)
class _FirstPageState extends State<FirstPage> {
final List<Tab> myTabs = <Tab>[
Tab(text: '全部订单'),
Tab(text: '已完成'),
Tab(text: '未完成')
];
@override
Widget build(BuildContext context) {
// 1. 使用 DefaultTabController 作为外层控制器
return DefaultTabController(
length: myTabs.length,// 定义tab数量
child: Scaffold(
appBar: AppBar(
title: Text('FirstPage'),
// 2. 使用 TabBar
bottom: TabBar(
tabs: myTabs // 定义TabWeight,若数量和定义不一致会报错
),
),
// 3. 使用 TabBarView
body: TabBarView(
children: <Widget>[
/// 全部订单
Center(child: Text('全部订单')),
/// 已完成订单
Center(child: Text('已完成')),
/// 未完成订单
Center(child: Text('未完成'))
]),
),
);
}
}
效果如下:
方法二:TabController
实现SingleTickerProviderStateMixin
,重写初始化和注销方法,利用控制器TabController
管理和更多操作,其实第一种方法内部也是由TabController实现的。
// 1. 实现 SingleTickerProviderStateMixin
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
TabController _tabController;
static const List<Tab> _homeTopTabList = <Tab>[
Tab(text: '音乐', icon: Icon(Icons.music_note)),
Tab(text: '体育', icon: Icon(Icons.directions_run)),
Tab(text: '天气', icon: Icon(Icons.cloud_queue)),
Tab(text: '科技', icon: Icon(Icons.toys))
];
// 2. 初始化状态
@override
void initState() {
super.initState();
// TabController的滚动事件会触发一次监听, 点击事件会触发两次监听(一次是正常触发,一次是tab的动画触发)
_tabController = TabController(length: _homeTopTabList.length, vsync: this);
// 添加监听获取tab选中下标
_tabController.addListener((){
_currentTopTabIndex = _tabController.index;
});
}
// 3. 注销状态
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
// 4. 添加TabBar
bottom: TabBar(
tabs: _homeTopTabList,
controller: _tabController
),
),
// 5. 添加TabBarView
body: TabBarView(
controller: _tabController,
children: <Widget>[
_tabMusic(context),
_tabSport(context),
_tabSport(context),
_tabSport(context)
],
),
);
}
关于TabController 的监听有个坑 踩坑TabBar之TabController.addListener