和尚今天学习一下经常使用的 TabBar 导航栏使用方法;android
源码分析
const TabBar({
Key key,
@required this.tabs, // 顶部标签 Tab 组件列表
this.controller, // 顶部标签 Tab 控制器
this.isScrollable = false, // 标签 Tab 是否可滑动
this.indicatorColor, // 底部指示器颜色
this.indicatorWeight = 2.0, // 底部指示器高度
this.indicatorPadding = EdgeInsets.zero, // 底部指示器内边距
this.indicator, // 指示器样式
this.indicatorSize, // 指示器宽度
this.labelColor, // 标签 Tab 内容颜色
this.labelStyle, // 标签 Tab 内容样式
this.labelPadding, // 标签 Tab 内边距
this.unselectedLabelColor, // 未选中标签 Tab 颜色
this.unselectedLabelStyle, // 未选中标签 Tab 样式
this.dragStartBehavior = DragStartBehavior.start,
this.onTap,
})
const TabBarView({
Key key,
@required this.children, // 每一个 Tab 对应的 Widgets
this.controller, // 导航栏控制器
this.physics, // 滑动动画
this.dragStartBehavior = DragStartBehavior.start, // 处理拖拽开始行为方式
})
分析源码可得,TabBar 与 TabBarView 是配对使用的,其对应的 Tab 数量必须相同;其中 TabBar 中提供了众多相关指示器属性,且 TabBar 与 TabBarView 上下拖拽方式区分设置,互不影响;web
案例尝试
TabBar
-
tabs 为顶部标签列表; controller 为标签控制器,若未提供此标签控制器,可以使用系统 DefaultTabController 控制器;和尚建立一个基本的 TabBar 样式,其中 TabBar 与 TabBarView 共用一个 TabController 控制器,且对应数量一致;
// 设置 TabController
class _TabBarPageState extends State<TabBarPage> with SingleTickerProviderStateMixin {
TabController _tabController;
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
void initState() {
super.initState();
_tabController = new TabController(vsync: this, length: 4);
}
@override
Widget build(BuildContext context) => MaterialApp(home: Scaffold(
appBar: AppBar(title: Text('TabBar Page'),
bottom: TabBar(tabs: <Widget>[
Tab(text: '今日爆款'), Tab(text: '土货生鲜'), Tab(text: '会员中心'), Tab(text: '分类')
], controller: _tabController)),
body: TabBarView(controller: _tabController, children: <Widget>[
Center(child: Text('今日爆款')), Center(child: Text('土货生鲜')), Center(child: Text('会员中心')), Center(child: Text('分类'))
])));
}
==========================================================================================================================================
// 未提供 TabController,使用 DefaultTabController 方式
@override
Widget build(BuildContext context) => DefaultTabController(length: 4,
child: Scaffold(appBar: AppBar(title: Text('TabBar Page'),
bottom: TabBar(tabs: <Widget>[
Tab(text: '今日爆款'), Tab(text: '土货生鲜'), Tab(text: '会员中心'), Tab(text: '分类')
])),
body: TabBarView(children: <Widget>[
Center(child: Text('今日爆款')), Center(child: Text('土货生鲜')), Center(child: Text('会员中心')), Center(child: Text('分类'))
])));
-
isScrollable 为标签栏是否可滑动,若设为 true 可按照每一个标签宽度延伸,总体可超过屏幕宽度,若不超过屏幕宽度居中展现;若设为 false 则以屏幕宽度为准,多个标签均分宽度;
isScrollable: true/false
-
indicatorColor 为底部指示器颜色; indicatorWeight 为底部指示器高度; indicatorPadding 为底部指示器内边距;
indicatorColor: Colors.redAccent,
indicatorWeight: 10,
indicatorPadding: EdgeInsets.all(5),
-
indicatorSize 为指示器宽度,其中包括指示器 indicatorPadding 内边距宽度;为 TabBarIndicatorSize, TabBarIndicatorSize.tab 与分配的单个 Tab 宽度; TabBarIndicatorSize.label 为单个 Tab 中 Widget 内容宽度;
indicatorSize: TabBarIndicatorSize.tab,
indicatorSize: TabBarIndicatorSize.label,
-
labelColor 为 Tab 标签内容颜色; labelStyle 为 Tab 标签样式; labelPadding 为 Tab 内边距;当 labelColor 和 labelStyle 均设置颜色时以 labelColor 为准;但若是 Tab 中 Widgets 设置样式时以 Tab 设置为准, labelStyle 不生效;
// tabs 内容
Tab(text: '今日爆款'), Tab(text: '土货生鲜'), Tab(text: '会员中心'),
Tab(child: Text('分类', style: TextStyle(color: Colors.black, fontSize: 18))),
labelColor: Colors.redAccent,
labelStyle: TextStyle(color: Colors.green, fontSize: 16),
-
unselectedLabelColor 为未选中标签颜色; unselectedLabelStyle 为未选中标签样式;当 unselectedLabelColor 和 unselectedLabelStyle 均设置颜色时以 unselectedLabelColor 为准;但若是 Tab 中 Widgets 设置样式时以 Tab 设置为准, unselectedLabelStyle 不生效;
labelColor: Colors.redAccent,
labelStyle: TextStyle(color: Colors.green, fontSize: 16),
unselectedLabelColor: Colors.white,
unselectedLabelStyle: TextStyle(fontSize: 14),
dragStartBehavior 为处理拖拽开始行为方式,DragStartBehavior.start 为初始位置为拖动开始位置;DragStartBehavior.down 为初始位置为点击触摸下位置;和尚对此理解不够深刻,但愿更清楚的朋友多多交流;微信
dragStartBehavior: DragStartBehavior.down,
TabBarView
physics 为通用的滑动动画,能够设置是否滑动或其余滑动模式;可经过 NeverScrollableScrollPhysics() 禁止滑动切换 Tab;app
physics: NeverScrollableScrollPhysics(),
小扩展
TabBar 通常使用在 AppBar bottom 中,上面会有 Title 层,和尚尝试,TabBar 也能够直接应用在 Title 处;ide
Scaffold(appBar: AppBar(title: _tabBarBottom()), body: _tabBarView())
Scaffold(appBar: AppBar(
title: _tabBarBottom(), leading: Icon(Icons.android),
actions: <Widget>[Padding(padding: EdgeInsets.symmetric(horizontal: 10), child: Icon(Icons.list))]),
body: _tabBarView())
TabBar 案例源码源码分析
和尚对 TabBar 的应用不够深刻,下节重点尝试自定义 indicator;若有错误请多多指导!学习
来源:阿策小和尚动画
本文分享自微信公众号 - 阿策小和尚(gh_8297e718c166)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。ui