home.dart子页面主要代码:
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>
with SingleTickerProviderStateMixin {
late TabController _tabController;
//生命周期函数:初始化时触发
@override
void initState() {
super.initState();
_tabController = TabController(length: 9, vsync: this);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
//背景颜色
backgroundColor: Colors.white,
//阴影高度
elevation: 0,
title: TabBar(
//是否可滚动
isScrollable: true,
controller: _tabController,
//指示器高度
indicatorWeight: 1,
//指示器边距
// indicatorPadding: const EdgeInsets.all(2),
//选中字体颜色
labelColor: Colors.white,
//未选中字体颜色
unselectedLabelColor: Colors.grey,
//指示器宽度,默认tab:撑满选项卡宽度; label:宽度跟随内容,不撑满选项卡
// indicatorSize: TabBarIndicatorSize.label,
//指示器颜色
// indicatorColor: Colors.white,
//指示器Decoration
indicator: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(10),
),
//选中label样式
labelStyle: const TextStyle(fontSize: 15),
//未选中label样式
unselectedLabelStyle: const TextStyle(fontSize: 14),
tabs: const [
Tab(
child: Text("关注"),
),
Tab(
child: Text("热门"),
),
Tab(
child: Text("视频"),
),
Tab(
child: Text("关注"),
),
Tab(
child: Text("热门"),
),
Tab(
child: Text("视频"),
),
Tab(
child: Text("关注"),
),
Tab(
child: Text("热门"),
),
Tab(
child: Text("视频"),
),
],
),
),
body: TabBarView(
controller: _tabController,
children: const [
Center(
child: Text("关注"),
),
Center(
child: Text("热门"),
),
Center(
child: Text("视频"),
),
Center(
child: Text("关注"),
),
Center(
child: Text("热门"),
),
Center(
child: Text("视频"),
),
Center(
child: Text("关注"),
),
Center(
child: Text("热门"),
),
Center(
child: Text("视频"),
),
],
),
);
}
}
首先需要with SingleTickerProviderStateMixin方法,然后initState生命周期函数中设置Tab长度,最后在Scaffold中设置TabBar和TabBarView。
appBar高度设置:
appBar: PreferredSize(
//appBar高度设置
preferredSize: const Size.fromHeight(40),
child: AppBar(
//背景颜色
backgroundColor: Colors.transparent,
//阴影高度
elevation: 0,
title: TabBar(
//是否可滚动
isScrollable: true,
controller: _tabController,
//指示器高度
// indicatorWeight: 1,
//指示器边距
indicatorPadding: const EdgeInsets.all(5),
//选中字体颜色
labelColor: Colors.red,
//指示器颜色
indicatorColor: Colors.red,
//指示器Decoration
/* indicator: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(10),
),*/
//未选中字体颜色
unselectedLabelColor: Colors.black,
//指示器宽度,默认tab:撑满选项卡宽度; label:宽度跟随内容,不撑满选项卡
indicatorSize: TabBarIndicatorSize.label,
//选中label样式
labelStyle: const TextStyle(fontSize: 15),
//未选中label样式
unselectedLabelStyle: const TextStyle(fontSize: 15),
//只监听点击事件,多次点击同一个tab且每次都会监听
/*onTap: (index) {
print(index);
},*/
tabs: const [
Tab(
child: Text("关注"),
),
Tab(
child: Text("热门"),
),
Tab(
child: Text("视频"),
),
Tab(
child: Text("关注"),
),
Tab(
child: Text("热门"),
),
Tab(
child: Text("视频"),
),
Tab(
child: Text("关注"),
),
Tab(
child: Text("热门"),
),
Tab(
child: Text("视频"),
),
],
),
),
),
AppBar外嵌套PreferredSize组件,PreferredSize组件中通过preferredSize: const Size.fromHeight(40),属性设置AppBar的高度。
onTap属性只监听点击事件,多次点击同一个tab且每次都会监听。
TabController监听事件:
@override
void initState() {
super.initState();
_tabController = TabController(length: 9, vsync: this);
//监听_tabController事件的改变(滑动和点击都会监听,且同一tab多次点击只监听一次)
_tabController.addListener(() {
if (_tabController.animation?.value == _tabController.index) {
print(_tabController.index);
}
});
}
///生命周期函数,组件销毁时触发
@override
void dispose() {
super.dispose();
_tabController.dispose();
}
TabController滑动和点击都会监听,且同一tab多次点击只监听一次。
dispose()为生命周期销毁函数。
TabBar下的主要属性代码中已注释,更多属性请参考源码:
const TabBar({
super.key,
required this.tabs,
this.controller,
this.isScrollable = false,
this.padding,
this.indicatorColor,
this.automaticIndicatorColorAdjustment = true,
this.indicatorWeight = 2.0,
this.indicatorPadding = EdgeInsets.zero,
this.indicator,
this.indicatorSize,
this.dividerColor,
this.labelColor,
this.labelStyle,
this.labelPadding,
this.unselectedLabelColor,
this.unselectedLabelStyle,
this.dragStartBehavior = DragStartBehavior.start,
this.overlayColor,
this.mouseCursor,
this.enableFeedback,
this.onTap,
this.physics,
this.splashFactory,
this.splashBorderRadius,
}) : _isPrimary = true,
assert(indicator != null || (indicatorWeight > 0.0));
main.dart首页代码:
import 'package:flutter/material.dart';
import 'package:flutter_demo/tabs/category.dart';
import 'package:flutter_demo/tabs/home.dart';
import 'package:flutter_demo/tabs/people.dart';
import 'package:flutter_demo/tabs/setting.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
//隐藏DEBUG图标
debugShowCheckedModeBanner: false,
theme: ThemeData(primarySwatch: Colors.blue),
home: const Scaffold(
body: MyHomePage(),
),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const Tabs();
}
}
class Tabs extends StatefulWidget {
const Tabs({super.key});
@override
State<Tabs> createState() => _TabsState();
}
class _TabsState extends State<Tabs> {
int currentIndex = 0;
List<Widget> pages = const [
HomePage(),
CategoryPage(),
SettingPage(),
PeoplePage()
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Flutter"),
),
body: pages[currentIndex],
drawer: const Drawer(
child: Column(
children: [
Row(
children: [
Expanded(
flex: 1,
child: UserAccountsDrawerHeader(
accountName: Text("张三"),
accountEmail: Text("xxx@qq.com"),
currentAccountPicture: CircleAvatar(
backgroundImage: NetworkImage(
"https://www.itying.com/images/flutter/1.png"),
),
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
"https://www.itying.com/images/flutter/2.png"),
fit: BoxFit.cover,
),
),
),
),
],
),
ListTile(
leading: CircleAvatar(
child: Icon(
Icons.people,
),
),
title: Text("个人中心"),
),
Divider(),
ListTile(
leading: CircleAvatar(
child: Icon(
Icons.settings,
),
),
title: Text("系统设置"),
)
],
),
),
bottomNavigationBar: BottomNavigationBar(
//选中菜单颜色
fixedColor: Colors.blue,
//图标大小,默认24.0
iconSize: 30,
//第几个菜单选中
currentIndex: currentIndex,
//当item数量大于3个时需要设置type属性
type: BottomNavigationBarType.fixed,
unselectedItemColor: Colors.grey.shade600,
onTap: (index) {
setState(() {
currentIndex = index;
});
},
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: "首页",
),
BottomNavigationBarItem(
icon: Icon(Icons.category),
label: "分类",
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
label: "设置",
),
BottomNavigationBarItem(
icon: Icon(Icons.people),
label: "用户",
),
],
),
);
}
}