文章目录
AppBar自定义顶部按钮图标、颜色
属性 | 描述 |
---|---|
leading | 在标题前面显示的一个控件,在首页通常显示应用的logo;在其他页面通常显示为返回按键 |
title | 标题,通常显示为当前页面的标题文字,可以放组件 |
actions | 通常使用IconButton来表示,可以放按钮组件 |
bottom | 通常放tabBar ,标题下面显示一个Tab导航栏 |
backgroundColor | 导航栏背景颜色 |
iconTheme | 图标样式 |
centerTitle | 标题是否居中显示 |
取消debug图标
return MaterialApp(
debugShowCheckedModeBanner: false ,//去掉debug图标
home:Tabs(),
...
)
TabBar TabBarView来实现顶部导航
- 混入
SingleTickerProviderStateMixin
class _HomePage extends State<HomePage> with SingleTickerProviderStateMixin{}
- 定义
TabController
late TabController _tabController;
void initState() {
//TODO: implement initState
super.initState();
_tabController = TabController(length: 3,vsync: this)
}
其实在
Scaffold组件
中还可以嵌套Scaffold
,这里我们以home.dart
为例子
//tabs.dart
class _TabsState extends State<Tabs>{
int _currentIndex = 0;
final List<Widget> _pages = const [
HomePage(),
MessagePage(),
MyPage(),
];
Widget build(BuildContext context) {
return Scaffold(
appBar: null, //标题为null
drawer: const Drawer(
child: Text("左侧侧边栏"),
),
body: _pages[_currentIndex], //修改
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (index) {
//index:点击索引值
// print(index);
setState(() {
_currentIndex = index;
});
},
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: "首页"),
BottomNavigationBarItem(icon: Icon(Icons.message), label: "消息"),
BottomNavigationBarItem(
icon: Icon(Icons.my_library_add_outlined), label: "我的")
],
),
floatingActionButton: Container(
width: 60, //调整FloatingActionButton大小
height: 60, //调整FloatingActionButton大小
padding: const EdgeInsets.all(5),
margin: const EdgeInsets.only(top: 10), //调整FloatingActionButton位置
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(30)),
child: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.add),
),
),
floatingActionButtonLocation: FloatingActionButtonLocation
.centerDocked, //floatingActionButtonLocation来调整floatingActionButton的位置
);
}
}
//home.dart(这里进行标头和顶部导航配置)
class _HomePageState extends State<HomePage>
with SingleTickerProviderStateMixin {
late TabController _tabController;
void initState() {
super.initState();
_tabController = TabController(length: 3, vsync: this);//标头数量
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar( //一如既往的AppBar头
leading: const CircleAvatar(
backgroundImage: NetworkImage(
"https://i2.hdslb.com/bfs/face/ce2494fac2fd854dd2813b8960521d8e0d1a527c.jpg@150w_150h.jpg"),
),
bottom: TabBar( //标头
controller: _tabController,
tabs: const [
Tab(child: Text("推荐")),
Tab(child: Text("热门")),
Tab(
child: Text("动画"),
)
],
),
),
body: TabBarView(//这里配置相应标头所对应的页面
controller: _tabController,
children: const [Text("我的关注"), Text("我的热门"), Text("我的动漫")],
),
);
}
}
PreferredSize组件
PreferredSize
可以改变appBar的高度
Scaffold(
appBar:PreferredSize(//可以配置AppBar的高度
preferredSize: Size.fromHeight(50),
child: AppBar()
),
body: Text()
)
改变TabBar导航样式
TabBar(
isScrollable: true, //设置可以滚动
indicatorColor: Colors.yellow, //底部指示器的颜色
labelColor: Colors.green, //label选中颜色
unselectedLabelColor: Colors.black, //label未选中的颜色
indicatorSize: TabBarIndicatorSize.label, //修改指示长幅度,label:与字体同宽
labelStyle: TextStyle(/*fontSize: number,...*/)
controller: _tabController,
tabs: ...
body: ..
)
修改
TabBar
可以通过Container
,但我们是通过以上的写法,TabBar
在bottom
,所以我们不能使用Container(可以使用在title中)
自定义KeepAliveWrapper缓存页面
class KeepAliveWrapper extends StatefulWidget{
...
State<KeepAliveWrapper> createState() => _KeepAliveWrapperState();
}
class _KeepAliveWrapperState extends State<KeepAliveWrapper> with AutomaticKeepAliveClientMixin{ //主要是AutomaticKeepAliveClientMixin
}
//KeepAliveWrapper.dart
import 'package:flutter/cupertino.dart';
class KeepAliveWrapper extends StatefulWidget {
const KeepAliveWrapper(
{super.key, this.child, this.keepAlive = true});
final Widget? child;
final bool keepAlive;
State<KeepAliveWrapper> createState() => _KeepAliveWrapperState();
}
class _KeepAliveWrapperState extends State<KeepAliveWrapper>
with AutomaticKeepAliveClientMixin {
Widget build(BuildContext context) {
return widget.child!; //可以通过widget拿到父组件的属性
}
bool get wantKeepAlive => widget.keepAlive; //默认缓存页面是因为我们自己设置的keepAlive本身为true
}
使用
TabBarView(
controller: _tabController,
children: [
const Text("直播"),
const TuiJianPage(),
KeepAliveWrapper( //自定义缓存组件
child: ListView(
children: const [ListTile(title: Text("我是关注"))],
)),
const Text("我的动漫"),
const Text("我的影视"),
const Text("新征程"),
],
),
如何获取tab下的索引值
- 监听TabController下的事件
//记住,这个生命周期是初始化,所以要重启项目才生效
void initState() {
super.initState();
_tabController = TabController(length: 6, vsync: this);
_tabController.addListener(() {
//print(_tabController.index); //获取点击或滑动页面的索引值
if (_tabController.animation!.value == _tabController.index) {
print(_tabController.index);//获取点击或滑动页面的索引值
}
});
}
- TabBar的
onTap
TabBar(
isScrollable: true, //设置可以滚动
indicatorColor: Colors.red, //底部指示器的颜色
labelColor: Colors.red, //label选中颜色
unselectedLabelColor: Colors.black, //label未选中的颜色
indicatorSize: TabBarIndicatorSize.label, //修改指示长幅度,label:与字体同宽
controller: _tabController,
tabs: const [
Tab(child: Text("直播")),
Tab(child: Text("推荐")),
Tab(child: Text("热门")),
Tab(child: Text("动画")),
Tab(child: Text("影视")),
Tab(child: Text("新征程")),
],
onTap: (index) {
//只能监听点击事件,没办法监听滑动
print(index);
},
),
销毁组件
//dispose:组件销毁的时候触发
void dispose() {
super.dispose();
//销毁_tabController
_tabController.dispose();
}
这样的话我们的状态会丢失