# expandable_bottom_sheet **Repository Path**: luy7788/expandable_bottom_sheet ## Basic Information - **Project Name**: expandable_bottom_sheet - **Description**: 仿高德地图,底部拖出控件 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: dev - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-01-15 - **Last Updated**: 2024-01-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ExpandableBottomSheet *This is a BottomSheet with a draggable height like the Google Maps App on Android.* If you have suggestions or find bugs please write an issue at [github](https://github.com/torbenkeller/expandable_bottom_sheet/issues). PR's are welcome.
## Arguments Argument | Description --- | --- expandableContent | This is the widget which you can hide and show by dragging. It has to be a widget with a constant height. background | This is the widget behind the `expandableContent` which holds usually the content of your page. persistentHeader | This is a Widget which is on top of the `expandableContent` and will never be hidden. It is made for a widget which indicates the user he can expand the content by dragging. persistentFooter | This is a widget which is always shown at the bottom. The `expandableContent`is if it is expanded on top of it so you don't need margin to see all of your content. You can use it for example for navigation or a menu. persistentContentHeight | This is the height of the content which will never been contracted. It only relates to `expandableContent`. `persistentHeader` and `persistentFooter` will not be affected by this. animationDurationExtend | This is the duration for the animation if you stop dragging with high speed. animationDurationContract | is the duration for the animation to bottom if you stop dragging with high speed. If it is `null` `animationDurationExtend` will be used. animationCurveExpand | This is the curve of the animation for expanding the `expandableContent` if the drag ended with high speed. animationCurveContract | This is the curve of the animation for contracting the `expandableContent` if the drag ended with high speed. onIsExtendedCallback | This will be executed if the extend reaches its maximum. onIsContractedCallback | This will be executed if the extend reaches its minimum. enableToggle | This will enable tap to toggle option on header. # Examples This are two examples how to use the ExpandableBottomSheet ## Import Library ```dart import 'package:expandable_bottom_sheet/expandable_bottom_sheet.dart'; ``` ## Easy Example ```dart ExpandableBottomSheet( background: Container( color: Colors.red, child: Center( child: Text('Background'), ), ), persistentHeader: Container( height: 40, color: Colors.blue, child: Center( child: Text('Header'), ), ), expandableContent: Container( height: 500, color: Colors.green, child: Center( child: Text('Content'), ), ), ); ``` ## Call expand, contract or status programmatically ```dart ... GlobalKey key = new GlobalKey(); ... @override Widget build(BuildContext context) { return ExpandableBottomSheet( key: key ... ); } void expand() => key.currentState.expand(); void contract() key.currentState.contract(); ExpansionStatus status() => key.currentState.expansionStatus; ``` ## Expert Example ```dart class ExampleExpert extends StatefulWidget { @override _ExampleExpertState createState() => _ExampleExpertState(); } class _ExampleExpertState extends State { GlobalKey key = new GlobalKey(); int _contentAmount = 0; ExpansionStatus _expansionStatus = ExpansionStatus.contracted; @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text(_expansionStatus.toString()), ), body: ExpandableBottomSheet( //use the key to get access to expand(), contract() and expansionStatus key: key, //optional //callbacks (use it for example for an animation in your header) onIsContractedCallback: () => print('contracted'), onIsExtendedCallback: () => print('extended'), //optional; default: Duration(milliseconds: 250) //The durations of the animations. animationDurationExtend: Duration(milliseconds: 500), animationDurationContract: Duration(milliseconds: 250), //optional; default: Curves.ease //The curves of the animations. animationCurveExpand: Curves.bounceOut, animationCurveContract: Curves.ease, //optional //The content extend will be at least this height. If the content //height is smaller than the persistentContentHeight it will be //animated on a height change. //You can use it for example if you have no header. persistentContentHeight: 220, //required //This is the widget which will be overlapped by the bottom sheet. background: Container( color: Colors.blue[800], ), //optional //This widget is sticking above the content and will never be contracted. persistentHeader: Container( color: Colors.orange, constraints: BoxConstraints.expand(height: 40), child: Center( child: Container( height: 8.0, width: 50.0, color: Color.fromARGB((0.25 * 255).round(), 0, 0, 0), ), ), ), //required //This is the content of the bottom sheet which will be extendable by dragging. expandableContent: Container( constraints: BoxConstraints(maxHeight: 400), child: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, children: [ for (int i = 0; i < _contentAmount; i++) Container( height: 50, color: Colors.red[((i % 8) + 1) * 100], ), ], ), ), ), //optional //This is a widget aligned to the bottom of the screen and stays there. //You can use this for example for navigation. persistentFooter: Container( color: Colors.green, height: 100, child: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ IconButton( icon: Icon(Icons.add), onPressed: () => setState(() { _contentAmount++; }), ), IconButton( icon: Icon(Icons.arrow_upward), onPressed: () => setState(() { key.currentState!.expand(); }), ), IconButton( icon: Icon(Icons.cloud), onPressed: () => setState(() { _expansionStatus = key.currentState!.expansionStatus; }), ), IconButton( icon: Icon(Icons.arrow_downward), onPressed: () => setState(() { key.currentState!.contract(); }), ), IconButton( icon: Icon(Icons.remove), onPressed: () => setState(() { if (_contentAmount > 0) _contentAmount--; }), ), ], ), ), ), ), ); } } ```