转载请声明出处!!!
什么是SliverAppBar
SliverAppBar 类似于Android中的CollapsingToolbarLayout
,可以轻松实现页面头部展开、合并的效果。 与AppBar大部分的属性重合,相当于AppBar的加强版
现在大部分app在一些页面都会有在用户在下拉页面的时候固定显示bar而在页面顶部的隐藏此部分,这个功能是可以用SliverAppBar和监听页面滚动来实现的
效果图:
首先创建一个ScrollController因为我们要用到CustomScrollView,在创建一个bool来判断是否要显示bar
添加监听页面滚动 判断的范围可以根据业务需求更改
ini
void _onScroll() {
// 获取当前滚动位置的偏移量
final offset = _scrollController.offset;
// 当滚动偏移量超过10,并且当前显示 AppBar 状态为 false 时,更新状态使 AppBar 显示
if (offset > 10 && !showAppBar) {
setState(() => showAppBar = true);
}
// 当滚动偏移量小于等于10,并且当前显示 AppBar 状态为 true 时,更新状态使 AppBar 隐藏
else if (offset <= 10 && showAppBar) {
setState(() => showAppBar = false);
}
}
通过SliverLayoutBuilder来控制是否要显示SliverAppbar,SliverLayoutBuilder是一个可以在 Sliver 中动态构建 UI 的组件,允许你基于 SliverConstraints
动态调整 Sliver 布局。
less
SliverLayoutBuilder(
builder: (context, constraints) {
return showAppBar
? SliverAppBar(
pinned: true, //是否固定
backgroundColor: Colors.white,
elevation: 0,
automaticallyImplyLeading: false,
toolbarHeight: 43.h,
flexibleSpace: FlexibleSpaceBar(
collapseMode: CollapseMode.pin,
background: _buildHeaderBar(),
),
)
: SliverToBoxAdapter(child: SizedBox.shrink());
},
),
全部代码:
less
class MySliverPage extends StatefulWidget {
@override
_MySliverPageState createState() => _MySliverPageState();
}
class _MySliverPageState extends State<MySliverPage> {
final ScrollController _scrollController = ScrollController();
bool showAppBar = false;
void _onScroll() {
// 获取当前滚动位置的偏移量
final offset = _scrollController.offset;
// 当滚动偏移量超过10,并且当前显示 AppBar 状态为 false 时,更新状态使 AppBar 显示
if (offset > 10 && !showAppBar) {
setState(() => showAppBar = true);
}
// 当滚动偏移量小于等于10,并且当前显示 AppBar 状态为 true 时,更新状态使 AppBar 隐藏
else if (offset <= 10 && showAppBar) {
setState(() => showAppBar = false);
}
}
@override
void initState() {
super.initState();
_scrollController.addListener(_onScroll);
}
@override
void dispose() {
_scrollController.removeListener(_onScroll);
_scrollController.dispose();
super.dispose();
}
Widget _buildHeaderBar() {
return Column(
children: [
30.h.heightBox,
Row(
children: [
15.w.widthBox,
ClipRRect(
borderRadius: BorderRadius.circular(15),
child: SizedBox(
width: 30.w,
height: 30.w,
child: CachedNetworkImage(
imageUrl: 'https://img2.baidu.com/it/u=3901868821,1751410039&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500',
fit: BoxFit.cover,
),
),
),
10.w.widthBox,
Text("lynxx", style: TextStyle(fontSize: 12.sp, color: Colors.black)),
Spacer(),
IconButton(
onPressed: () {},
icon: Icon(Icons.settings, color: Colors.black, size: 15),
),
],
),
],
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
controller: _scrollController,
slivers: [
// 通过 SliverLayoutBuilder 来控制是否插入 SliverAppBar
SliverLayoutBuilder(
builder: (context, constraints) {
return showAppBar
? SliverAppBar(
pinned: true, //是否固定
backgroundColor: Colors.white,
elevation: 0,
automaticallyImplyLeading: false,
toolbarHeight: 43.h,
flexibleSpace: FlexibleSpaceBar(
collapseMode: CollapseMode.pin,
background: _buildHeaderBar(),
),
)
: SliverToBoxAdapter(child: SizedBox.shrink());
},
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => ListTile(title: Text("Item $index")),
childCount: 50,
),
),
],
),
);
}
}
觉得有帮助的点点赞😊