我正试图从
find my
iOS上的应用程序。
我用过
draggableScrollableSheet
但它不如上的那个好用
找到我的
.
class DraggableSheet extends StatefulWidget {
final Widget child;
final String title;
const DraggableSheet({super.key, required this.child, required this.title});
@override
State<DraggableSheet> createState() => _DraggableSheetState();
}
class _DraggableSheetState extends State<DraggableSheet> {
final sheet = GlobalKey();
final controller = DraggableScrollableController();
@override
void initState() {
super.initState();
controller.addListener(onChanged);
}
void onChanged() {
final currentSize = controller.size;
if (currentSize <= 0.10) collapse();
}
void collapse() => animateSheet(getSheet.snapSizes!.first);
void anchor() => animateSheet(getSheet.snapSizes!.last);
void expand() => animateSheet(getSheet.maxChildSize);
void hide() => animateSheet(getSheet.minChildSize);
void animateSheet(double size) {
controller.animateTo(
size,
duration: const Duration(milliseconds: 100),
curve: Curves.easeIn,
);
}
@override
void dispose() {
super.dispose();
controller.dispose();
}
DraggableScrollableSheet get getSheet =>
(sheet.currentWidget as DraggableScrollableSheet);
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, constraints) {
return DraggableScrollableSheet(
key: sheet,
snapAnimationDuration: const Duration(milliseconds: 100),
initialChildSize: 0.157,
maxChildSize: 0.93,
minChildSize: 0,
expand: true,
snap: true,
snapSizes: const [
0.157,
0.4,
0.93,
],
controller: controller,
builder: (BuildContext context, ScrollController scrollController) {
return DecoratedBox(
decoration: BoxDecoration(
color: CupertinoTheme.of(context).scaffoldBackgroundColor,
boxShadow: const [
BoxShadow(
color: Colors.black12,
blurRadius: 10,
spreadRadius: 1,
offset: Offset(0, 1),
),
],
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
),
),
child: CustomScrollView(
controller: scrollController,
slivers: [
BottomSheetHeader(title: widget.title),
SliverToBoxAdapter(
child: widget.child,
),
],
),
);
},
);
});
}
}
它缺少反弹捕捉动画,我不知道它们是如何显示按钮的
Add items
一个在第一次捕捉(大约一半屏幕大小),然后从主体展开(保持按钮在底部)。
BottomSheetHeader
class BottomSheetHeader extends StatelessWidget {
final String title;
const BottomSheetHeader({super.key, required this.title});
@override
Widget build(BuildContext context) {
return SliverPersistentHeader(
pinned: true,
delegate: SliverAppBarDelegate(
minHeight: 52,
maxHeight: 52,
child: Container(
decoration: BoxDecoration(
color: CupertinoTheme.of(context).scaffoldBackgroundColor,
),
child: Column(
children: [
Center(
child: Wrap(
children: <Widget>[
Container(
width: 36,
margin: const EdgeInsets.only(top: 4, bottom: 4),
height: 5,
decoration: const BoxDecoration(
color: Colors.black26,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
),
],
),
),
Row(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: Text(
title,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
],
),
const SizedBox(height: 8.0),
const Divider(
height: 0,
),
],
),
),
),
);
}
}
class SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
SliverAppBarDelegate({
required this.minHeight,
required this.maxHeight,
required this.child,
});
final double minHeight;
final double maxHeight;
final Widget child;
@override
double get minExtent => minHeight;
@override
double get maxExtent => max(maxHeight, minHeight);
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return SizedBox.expand(child: child);
}
@override
bool shouldRebuild(SliverAppBarDelegate oldDelegate) {
return maxHeight != oldDelegate.maxHeight ||
minHeight != oldDelegate.minHeight ||
child != oldDelegate.child;
}
}
有更好的方法吗?