Last active
November 1, 2023 04:43
-
-
Save caseycrogers/945e951eba8e98eb8d62a70f54f3ca38 to your computer and use it in GitHub Desktop.
Sheet that snaps between open and dismissed
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 DraggableYeetableSheet extends StatefulWidget { | |
const DraggableYeetableSheet({super.key}); | |
@override | |
State<DraggableYeetableSheet> createState() => _DraggableYeetableSheetState(); | |
} | |
class _DraggableYeetableSheetState extends State<DraggableYeetableSheet> { | |
final DraggableScrollableController sheetController = | |
DraggableScrollableController(); | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
home: Scaffold( | |
body: Stack( | |
children: [ | |
Container( | |
color: Colors.black, | |
), | |
// You probably want to not include this in the tree when it's min | |
// size is at zero. | |
// You can get the current size of the sheet by listening to the | |
// sheet controller. | |
// This is left as an exercise to the reader. | |
DraggableScrollableSheet( | |
snap: true, | |
controller: sheetController, | |
maxChildSize: 1, | |
initialChildSize: 0, | |
// This + the controller is the secret sauce. | |
minChildSize: 0, | |
builder: (context, scrollController) { | |
return ListView.builder( | |
controller: scrollController, | |
itemCount: 20, | |
itemBuilder: (context, index) { | |
return Container( | |
height: 100, | |
color: index.isEven ? Colors.green : Colors.grey, | |
); | |
}, | |
); | |
}, | |
), | |
], | |
), | |
floatingActionButton: FloatingActionButton( | |
child: const Icon(Icons.add), | |
onPressed: () async { | |
return sheetController.animateTo( | |
// If we're not visible, animate us to the top. Else, animate us | |
// to the bottom. | |
// You can customize this logic fairly arbitrarily to meet your | |
// needs. | |
// Note that if the sheet is not in the tree animate to will | |
// throw. Make sure it's only called while the sheet is in the | |
// tree. | |
sheetController.size == 0 ? 1 : 0, | |
duration: const Duration(milliseconds: 300), | |
curve: Curves.easeInOut, | |
); | |
}, | |
), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment