flutter:slivers实现悬浮、停靠吸顶、隐藏等view
一,代码:
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class MyviewDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("个人主页")),
body: CustomScrollView(
slivers: [
_buildFloatBox(),
_buildStickBox(),
_buildSliverList()
],
),
);
}
Widget _buildFloatBox() {
return SliverPersistentHeader(
floating: true,
delegate: FloatingSPHD(height: 54),
);
}
Widget _buildStickBox() {
return SliverPersistentHeader(
pinned: true,
delegate: FlexibleSPHD(min: 40, max: 80));
}
Widget _buildSliverList() {
return SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
return Container(
height: 50,
color: index % 2 == 0 ? Colors.white : Colors.black12,
width: double.infinity,
alignment: Alignment.center,
child: Text("我是第${index}个item"),
);
},
childCount: 30,
));
}
}
class FloatingSPHD extends SliverPersistentHeaderDelegate {
final double height;
FloatingSPHD({required this.height});
@override
Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
return Container(
height: height,
alignment: Alignment.center,
color: Colors.green,
child: const Text(
"悬浮Header",
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
);
}
@override
double get maxExtent => height;
@override
double get minExtent => height;
@override
bool shouldRebuild(covariant FloatingSPHD oldDelegate) {
return oldDelegate.height != height;
}
@override
PersistentHeaderShowOnScreenConfiguration get showOnScreenConfiguration =>
const PersistentHeaderShowOnScreenConfiguration(
minShowOnScreenExtent: double.infinity);
}
class FlexibleSPHD extends SliverPersistentHeaderDelegate {
final double max;
final double min;
FlexibleSPHD({required this.max, required this.min});
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
double progress = shrinkOffset / (max - min);
progress = progress > 1 ? 1 : progress;
return Container(
color: Color.lerp(Colors.blue, Colors.red, progress),
child: Column(children: [
const Text(
"可伸缩区域",
style: TextStyle(
color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold),
),
SizedBox(height: (1 - progress) * 20),
Opacity(
opacity: 1 - progress,
child: SizedBox(
height: (1 - progress) * 30,
child: const Text("需要隐藏部分",
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold)),
),
)
]),
);
}
@override
double get maxExtent => max;
@override
double get minExtent => min;
@override
bool shouldRebuild(covariant FlexibleSPHD oldDelegate) {
return oldDelegate.min != min || oldDelegate.max != max;
}
}
二,测试效果:
未上滑时:

下滑后:

浙公网安备 33010602011771号