flutter/lib/components/custom_sticky_header.dart

51 lines
1.3 KiB
Dart
Raw Permalink Normal View History

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;
}
}