SliverPersistentHeader
滑动到顶部时可以固定,实现收缩和增长效果的小部件。如果想对SliverAppBar
进行更多控制,或者想制作自己的自定义标题,可以使用SliverPersistentHeader
。
构造函数:
const SliverPersistentHeader({
super.key,
required this.delegate,//SliverPersistentHeaderDelegate
this.pinned = false,//true:SliverPersistentHeader介绍会以折叠高度固定显示在头部,false:缩小到折叠高度后滑出页面
this.floating = false,//true 的时候下滑先展示SliverPersistentHeader介绍,展示完成后才展示其他滑动组件内容
})
delegate
它需要一个扩展SliverPersistentHeaderDelegate
的类。我们必须覆盖具有 3 个参数的构建方法
Widget build(BuildContext context, double shrinkOffset, bool overlapsContent);
shrinkOffset
:child
偏移值minExtent~maxExtent
。overlapsContent
:SliverPersistentHeader
覆盖其他子组件返回true
,否则返回false
。
例子:
import 'dart:math';
import 'package:flutter/material.dart';
class SliverPersistentHeaderPage extends StatefulWidget {
const SliverPersistentHeaderPage({Key? key}) : super(key: key);
@override
State<SliverPersistentHeaderPage> createState() => _SliverPersistentHeaderPageState();
}
class _SliverPersistentHeaderPageState extends State<SliverPersistentHeaderPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: [
SliverPersistentHeader(
pinned: true,
delegate: MySliverHeader(maxExtent: 300,minExtent: 100)
),
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context,int index){
return Card(
margin: const EdgeInsets.all(15),
child: Container(
color: Colors.purple[100 * (index%9+1)],
height: 80,
alignment: Alignment.center,
child: Text(
'Iitem $index',
style: const TextStyle(fontSize: 30),
),
),
);
},
childCount: 1000,
)
)
],
),
);
}
}
class MySliverHeader extends SliverPersistentHeaderDelegate {
MySliverHeader({
required this.minExtent,
required this.maxExtent,
});
final double minExtent;//SliverPersistentHeader最小高度
final double maxExtent;//SliverPersistentHeader最大高度
@override
Widget build(BuildContext context,double shrinkOffset,bool overlapsContent){
print(shrinkOffset);
return Stack(
fit: StackFit.expand,
children: [
Image.asset("images/liu.webp",fit: BoxFit.cover,),
Positioned(
left: 15,
top: 25,
right: 15,
bottom: 15,
//标题透明度
child:Opacity(
opacity: 1.0 - max(0.0, shrinkOffset) / maxExtent,
child: Text("顶部标题",style: Theme.of(context).textTheme.headline3!.copyWith(
color: Colors.black,
),),
)
)
],
);
}
@override
bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
// TODO: implement shouldRebuild
// throw UnimplementedError();
return true;
}}