Flutter Widgets: TabBar
介绍
TabBar,是材料设计中很常用的一种横向标签页。在Android原生开发中,我们常用TabLayout或者一些常用的标签页开源库,来实现并行界面的横向滑动展示,在Flutter的世界中,TabBar有着相同的作用。通常,我们会在AppBar的底部部分结合TabBarView来使用TabBar。
类结构
构建TabBar,我们需要使用到多个Tab对象,用Tab来承载我们需要展示的Text和Icon内容,多个Tab呈现在用户面前,供用户点击切换内容。TabBar的构造方法中包含很多属性值或者变量。
属性 | 意义 |
---|---|
tabs | 一般使用Tab对象,当然也可以是其他的Widget |
controller | TabController对象 |
isScrollable | 是否可滚动 |
indicatorColor | 指示器颜色 |
indicatorWeight | 指示器厚度 |
indicatorPadding | 底部指示器的Padding |
indicator | 指示器decoration,例如边框等 |
indicatorSize | 指示器大小计算方式 |
labelColor | 选中Tab文字颜色 |
labelStyle | 选中Tab文字Style |
unselectedLabelColor | 未选中Tab中文字颜色 |
unselectedLabelStyle | 未选中Tab中文字style |
实践
tabs & isScrollable
tabs,List< Widget> ,一般我们使用Tab对象数组来填充这部分内容,因为Tab对象本身涵盖了我们常用的文字Tab,图标Tab或者是二者结合的形式。基本可以满足日常开发需求。
isScrollable,一般在Tab比较多的情况使用,默认为false,表示固定,每个tab的宽度将会以屏幕宽度为总和均分。若为true,超出屏幕范围的tabs,我们可以通过左右滚动访问。类似于HorizontalScrollView。
final List<Tab> myTabs = <Tab>[
new Tab(text: '语文'),
new Tab(text: '数学'),
new Tab(text: '英语'),
new Tab(text: '化学'),
new Tab(text: '物理'),
new Tab(text: '政治'),
new Tab(text: '经济'),
new Tab(text: '体育'),
];
……
Widget build(BuildContext context) {
return new DefaultTabController(
length: myTabs.length,
child: new Scaffold(
appBar: new AppBar(
bottom: new TabBar(
tabs: myTabs,
isScrollable: true,
),
),
body: new TabBarView(
children: myTabs.map((Tab tab) {
return new Center(child: new Text(tab.text));
}).toList(),
),
),
);
}
indicatorColor&indicatorWeight&indicatorPadding
indicatorColor: Colors.red,
indicatorWeight: 15.0,
indicatorPadding: new EdgeInsets.only(bottom: 30.0),
indicator
定义被选中的指示器的外观
indicator: new ShapeDecoration(shape: new Border.all(color: Colors.redAccent, width: 1.0)),
indicatorSize
定义指示器大小的计算方式,值取至TabBarIndicatorSize 这个枚举类型。从注释和下面的对比图片,可以显然看出,一个是以label的宽度为计算方式,一个是以整个Tab的宽度为计算方式。
enum TabBarIndicatorSize {
/// The tab indicator's bounds are as wide as the space occupied by the tab
/// in the tab bar: from the right edge of the previous tab to the left edge
/// of the next tab.
tab,
/// The tab's bounds are only as wide as the (centered) tab widget itself.
///
/// This value is used to align the tab's label, typically a [Tab]
/// widget's text or icon, with the selected tab indicator.
label,
}
indicatorSize: TabBarIndicatorSize.label
indicatorSize: TabBarIndicatorSize.tab
labelColor&labelStyle&unselectedLabelColor&unselectedLabelStyle
定义选中Tab和未选中Tab中文字的颜色和风格
labelColor: Colors.white,
labelStyle: new TextStyle(fontSize: 16.0),
unselectedLabelColor: Colors.black,
unselectedLabelStyle: new TextStyle(fontSize: 12.0)
TabController
TabBar和TabBarView通过公用的TabController对象来实现,互相之间的协调配合。
默认使用的是DefaultTabController.of(context)。用法如下。
Widget build(BuildContext context) {
return new DefaultTabController(length: myTabs.length,
child:
new Scaffold(
appBar: new AppBar(
bottom: new TabBar(
tabs: myTabs,
isScrollable: true,
indicatorSize: TabBarIndicatorSize.tab,
labelColor: Colors.white,
labelStyle: new TextStyle(fontSize: 16.0),
unselectedLabelColor: Colors.black,
unselectedLabelStyle: new TextStyle(fontSize: 12.0),
),
),
body: new TabBarView(
children: myTabs.map((Tab tab) {
return new Center(child: new Text(tab.text));
}).toList(),
),
),
);
}
当然,我们也能自定义TabController,保持TabBar和TabBarView使用的TabController一致即可。下面是官文中的使用样例。好东西都在源码中啊,很多不理解的内容,通过多阅读源码,可以找到头绪。
class MyDemo extends StatelessWidget {
final List<Tab> myTabs = <Tab>[
new Tab(text: 'LEFT'),
new Tab(text: 'RIGHT'),
];
@override
Widget build(BuildContext context) {
return new DefaultTabController(
length: myTabs.length,
child: new Scaffold(
appBar: new AppBar(
bottom: new TabBar(
tabs: myTabs,
),
),
body: new TabBarView(
children: myTabs.map((Tab tab) {
return new Center(child: new Text(tab.text));
}).toList(),
),
),
);
}
}