Last active
July 12, 2023 23:54
-
-
Save MarcinHradowicz/48214c5229db6f60b389d12817637ee8 to your computer and use it in GitHub Desktop.
ImprovedDraggableScrollableSheet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ImprovedDraggableScrollableSheet extends StatefulWidget { | |
const ImprovedDraggableScrollableSheet({Key? key}) : super(key: key); | |
@override | |
State<ImprovedDraggableScrollableSheet> createState() => _ImprovedDraggableScrollableSheetState(); | |
} | |
class _ImprovedDraggableScrollableSheetState extends State<ImprovedDraggableScrollableSheet> { | |
final GlobalKey commentsHeaderKey = GlobalKey(); | |
double commentsHeaderHeight = 0; | |
@override | |
void initState() { | |
super.initState(); | |
WidgetsBinding.instance.addPostFrameCallback((_) { | |
// Sets initial size of comments bottom sheet. Thanks to it users always see just a header of the bottom sheet at the beginning. | |
final double currentCommentsHeaderHeight = commentsHeaderKey.currentContext?.size?.height ?? 0; | |
if (currentCommentsHeaderHeight != commentsHeaderHeight) { | |
setState(() { | |
commentsHeaderHeight = currentCommentsHeaderHeight; | |
}); | |
} | |
}); | |
} | |
@override | |
Widget build(BuildContext context) { | |
final MediaQueryData mediaQueryData = MediaQuery.of(context); | |
final double heightOfDevice = mediaQueryData.size.height; | |
final double initialChildSize = | |
(commentsHeaderHeight + mediaQueryData.viewPadding.bottom + mediaQueryData.viewPadding.top) / heightOfDevice; | |
return DraggableScrollableSheet( | |
initialChildSize: initialChildSize, | |
minChildSize: initialChildSize, | |
maxChildSize: 1.0, | |
builder: (context, scrollController) { | |
return Container( | |
padding: EdgeInsets.only(bottom: mediaQueryData.viewPadding.bottom), | |
margin: EdgeInsets.only(top: mediaQueryData.viewPadding.top), | |
decoration: const BoxDecoration( | |
color: Color(0xffB1B2ff), | |
borderRadius: BorderRadius.vertical(top: Radius.circular(16)), | |
), | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.start, | |
children: [ | |
_CommentsHeader(key: commentsHeaderKey, scrollController: scrollController), | |
Expanded( | |
child: ListView.builder( | |
padding: EdgeInsets.zero, | |
itemCount: 30, | |
itemBuilder: (context, index) => Container( | |
color: index % 2 == 0 ? const Color(0xffAAC4FF) : const Color(0xffD2DAFF), | |
child: ListTile(title: Text('Comment $index')), | |
), | |
), | |
) | |
], | |
), | |
); | |
}, | |
); | |
} | |
} | |
class _CommentsHeader extends StatelessWidget { | |
const _CommentsHeader({ | |
Key? key, | |
required this.scrollController, | |
}) : super(key: key); | |
final ScrollController scrollController; | |
@override | |
Widget build(BuildContext context) { | |
return SingleChildScrollView( | |
physics: const ClampingScrollPhysics(), | |
controller: scrollController, | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: [ | |
const _CommentsHeaderPill(), | |
const Text('Comments'), | |
const SizedBox(height: 8), | |
Divider(color: Colors.black.withOpacity(0.5), height: 2, thickness: 2), | |
], | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment