2025-07-21 15:46:30 +08:00
|
|
|
/// 自定义粘性委托类
|
|
|
|
library;
|
|
|
|
|
|
|
|
import 'package:flutter/material.dart';
|
2025-08-21 10:50:38 +08:00
|
|
|
import 'package:get/get.dart';
|
|
|
|
|
|
|
|
typedef OnPinnedChanged = void Function(bool pinned);
|
2025-07-21 15:46:30 +08:00
|
|
|
|
|
|
|
class CustomStickyHeader extends SliverPersistentHeaderDelegate {
|
|
|
|
final PreferredSize child;
|
2025-08-21 10:50:38 +08:00
|
|
|
RxBool? isPinned;
|
|
|
|
RxDouble? positions;
|
2025-07-21 15:46:30 +08:00
|
|
|
|
2025-08-21 10:50:38 +08:00
|
|
|
CustomStickyHeader({
|
|
|
|
required this.child,
|
|
|
|
this.isPinned,
|
|
|
|
this.positions,
|
|
|
|
});
|
2025-07-21 15:46:30 +08:00
|
|
|
|
|
|
|
@override
|
|
|
|
double get minExtent => child.preferredSize.height;
|
|
|
|
|
|
|
|
@override
|
|
|
|
double get maxExtent => child.preferredSize.height;
|
|
|
|
|
|
|
|
@override
|
|
|
|
bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
|
2025-08-21 10:50:38 +08:00
|
|
|
// overlapsContent 或 shrinkOffset >= maxExtent - minExtent 都可以判断是否吸顶
|
|
|
|
bool pinned = overlapsContent; // true 表示已经吸顶
|
|
|
|
if (isPinned != null && isPinned!.value != pinned) {
|
|
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
|
|
isPinned!.value = pinned;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
if (positions != null) {
|
|
|
|
if ((maxExtent - minExtent) >= shrinkOffset) {
|
|
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
|
|
positions!.value = shrinkOffset;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-07-21 15:46:30 +08:00
|
|
|
return child;
|
|
|
|
}
|
|
|
|
}
|