一、创建基本的Tab组件
在Flutter中,我们可以使用Material Design风格的Tab,下面我们来看一个最基本的Tab组件:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final List
tabs =
[
Tab(text: 'Tab1'),
Tab(text: 'Tab2'),
Tab(text: 'Tab3'),
];
@override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: tabs.length,
child: Scaffold(
appBar: AppBar(
title: Text('Flutter Tab Demo'),
bottom: TabBar(
tabs: tabs,
),
),
body: TabBarView(
children:
[
Center(child: Text('This is Tab1')),
Center(child: Text('This is Tab2')),
Center(child: Text('This is Tab3')),
],
),
),
),
);
}
}
我们首先定义了一个包含三个Tab的List,然后在home中使用DefaultTabController包装Scaffold、AppBar和TabBarView便可实现默认的Tab组件,上方显示AppBar,下方使用了TabBar,TabView中展示三个页面,页面之间能够通过Tab进行切换。
二、自定义Tab样式
默认情况下,Tab的样式比较简单,但是我们完全可以自定义它的样式,比如Tab高度、字体样式等等。下面我们将Tab高度调整至30像素,并且将字体设为16像素:
class MyApp extends StatelessWidget {
final List
tabs =
[
Tab(text: 'Tab1'),
Tab(text: 'Tab2'),
Tab(text: 'Tab3'),
];
final TextStyle tabBarTextStyle =
TextStyle(fontSize: 16, fontWeight: FontWeight.w500);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: tabs.length,
child: Scaffold(
appBar: AppBar(
title: Text('Flutter Tab Demo'),
bottom: PreferredSize(
preferredSize: Size.fromHeight(30.0),
child: TabBar(
tabs: tabs,
labelStyle: tabBarTextStyle,
),
),
),
body: TabBarView(
children:
[
Center(child: Text('This is Tab1')),
Center(child: Text('This is Tab2')),
Center(child: Text('This is Tab3')),
],
),
),
),
);
}
}
在这个例子中,我们定义了一个TextStyle对象,将Tab字体设为16像素、加粗的样式。然后在TabBar的labelStyle中使用了这个TextStyle对象,Tab高度通过PreferredSize调整,实现了更加美观的Tab效果。
三、动态添加或删除Tab
在一些特殊情况下,我们需要动态添加或删除Tab,例如根据服务器数据返回的结果生成Tab。下面我们将演示动态添加一个Tab的方法:
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State
{
final List
tabs =
[];
int tabIndex = 0;
@override
void initState() {
super.initState();
tabs.add(Tab(text: 'Tab1'));
tabs.add(Tab(text: 'Tab2'));
}
void addTab() {
setState(() {
tabIndex++;
tabs.add(Tab(text: 'Tab$tabIndex'));
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: tabs.length,
child: Scaffold(
appBar: AppBar(
title: Text('Flutter Tab Demo'),
bottom: TabBar(
tabs: tabs,
),
),
body: TabBarView(
children: tabs.map((Tab tab) {
return Center(child: Text('This is ${tab.text}'));
}).toList(),
),
floatingActionButton: FloatingActionButton(
onPressed: addTab,
child: Icon(Icons.add),
),
),
),
);
}
}
在这个例子中,我们定义了一个空的Tab List,在initState方法中添加了两个Tab。然后我们在FloatingActionButton的onPressed方法中动态添加了一个Tab对象并刷新页面。
四、更加复杂的Tab使用场景
在实际开发中,我们可能需要更加复杂的Tab使用场景,例如Tab左侧显示一个icon,右侧显示一个Badge等等。下面我们将展示一个更好的Tab组件实现方法,包含左侧icon、右侧Badge、动画效果等等。
import 'package:flutter/material.dart';
class ComplexTab extends StatefulWidget {
@override
_ComplexTabState createState() => _ComplexTabState();
}
class _ComplexTabState extends State
{
final List
tabs =
[
_buildTab(icon: Icons.home, badgeCount: 5),
_buildTab(icon: Icons.mail, badgeCount: 3),
_buildTab(icon: Icons.person, badgeCount: 8),
];
static Widget _buildTab({IconData icon, int badgeCount}) {
return Stack(
children:
[
Tab(
icon: Icon(icon),
),
Visibility(
visible: badgeCount > 0,
child: Positioned(
top: 0,
right: 0,
child: Container(
padding: EdgeInsets.all(1),
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(10),
),
constraints: BoxConstraints(
minWidth: 18,
minHeight: 18,
),
child: Text(
'$badgeCount',
style: TextStyle(
color: Colors.white,
fontSize: 12,
),
textAlign: TextAlign.center,
),
),
),
),
],
);
}
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: tabs.length,
child: Scaffold(
appBar: AppBar(
title: Text('Complex Tab Demo'),
bottom: TabBar(
tabs: tabs,
isScrollable: true,
indicatorColor: Colors.transparent,
onTap: (index) {
setState(() {});
},
),
),
body: TabBarView(
children: tabs.map((Widget widget) {
return Center(child: widget);
}).toList(),
),
),
);
}
}
在这个例子中,我们定义了一个包含三个Widget的List,每个Widget都是一个Stack,包含了左侧icon和右侧Badge。右侧Badge通过一个包装有Text的Container实现,在数量变化时进行显示或隐藏操作,使用Visibility能够使badge不占据空间。TabBar中设置isScrollable为true时,当Tab数量非常多时会出现滚动条,增加用户体验,同时我们还加入Tab切换动画。
五、结语
到这里,我们已经阐述了Flutter Tab组件的使用方法和注意事项,可以用于实现基本的Tab组件和复杂的Tab组件。在实际开发中,我们能够根据需要自由地进行选择,实现自己的需求。