Flutter Tab组件是Flutter中很常用的一种组件,通常用于分组展示信息,或者展示不同的页面。在这篇文章中,我们将会从多个方面详细阐述Flutter Tab组件的使用方法和注意事项。
一、创建基本的Tab组件
在Flutter中,我们可以使用Material Design风格的Tab,下面我们来看一个最基本的Tab组件:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final List<Tab> tabs = <Tab>[
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: <Widget>[
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<Tab> tabs = <Tab>[
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: <Widget>[
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<MyApp> {
final List<Tab> 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<ComplexTab> {
final List<Widget> tabs = <Widget>[
_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: <Widget>[
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组件。在实际开发中,我们能够根据需要自由地进行选择,实现自己的需求。