Xiaocai found that when he failed to log in the Mi app market for a long time, there would be a sliding menu at the bottom of the half screen for users to download and promote. And in theFlutterThe half-screen bottom menu is not a simple oneBottomSheetCompleted, can passDraggableScrollableSheetAccording to the gesture operation, slide the fixed menu bar to complete; Simple dishes to learn;
DraggableScrollableSheet
Source code analysis
Const DraggableScrollableSheet({Key Key, this.initialChildSize = 0.5, // Initial ratio this.minChildSize = 0.25, MaxChildSize = 1.0, // maxChildSize this.expand = true, // Fill @required this.builder, }) @overridep Widget build(BuildContext context) { return LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { _extent.availablePixels = widget.maxChildSize * constraints.biggest.height; final Widget sheet = FractionallySizedBox( heightFactor: _extent.currentExtent, child: widget.builder(context, _scrollController), alignment: Alignment.bottomCenter, ); return widget.expand ? SizedBox.expand(child: sheet) : sheet; }); }Copy the code
Simple analysis of the source code DraggableScrollableSheet as a StatefulWidget Widget, FractionallySizedBox based on the parent Widget, can set the width and height ratio of containers to build child content;
Case try
1. builder
The ScrollableWidgetBuilder constructor is a required field for displaying slidable child content in the DraggableScrollableSheet; The returned content must be a slidable ScrollableWidget, such as ListView/GridView/SingleChildScrollView.
_listWid(controller) => SingleChildScrollView( controller: controller, child: Column(children: [ Container( height: Color: color.blue. WithOpacity (0.8), borderRadius: Borderradio.all (radio.Circular (16.0))), Margin: EdgeInsets. Symmetric (vertical: 12.0)), Padding(Padding: EdgeInsets. Symmetric (Horizontal: 12.0), Child: GridView.builder(physics: ScrollPhysics(), Primary: false, shrinkWrap: true, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 5, mainAxisSpacing: 8.0, crossAxisSpacing: 12.0, childAspectRatio: 0.7), itemCount: 12, itemBuilder: (context, index) => GestureDetector( child: Column(children: <Widget>[ PhysicalModel( color: Colors.transparent, shape: BoxShape.circle, clipBehavior: Clip.antiAlias, child: Image.asset('images/icon_hzw01.jpg')), SizedBox(height: 4), Text (" one piece ")]), onTap: () {}))), ListView. Builder (physics: NeverScrollableScrollPhysics (), shrinkWrap: true, itemCount: 15, itemBuilder: (BuildContext context, index) => ListTile(title: Text('Current Item = ${(index + 1)}'))) ]));Copy the code
2. initialChildSize
InitialChildSize is used to display the ratio of the initial child Widgets to the parent Widget. At the same time, if the returned child Widget does not provide a ScrollController, the DraggableScrollableSheet will not slide with the gesture. InitialChildSize = minChildSize = maxChildSize;
_sheetWid02() => DraggableScrollableSheet(initialChildSize: 0.66, Builder: (BuildContext context, ScrollController scrollController) => Container( decoration: BoxDecoration( color: Color.grey.withopacity (0.4), borderRadius: borderRadius. Only (topLeft: Radius. Circular (16.0), topRight: The Radius. Circular (16.0))), the child: _listWid (null)));Copy the code
3. minChildSize & maxChildSize
MinChildSize and maxChildSize correspond to the maximum and minimum proportion of child Widgets to the whole, where initialChildSize should be between the two.
_sheetWid03() => DraggableScrollableSheet(initialChildSize: 0.6, minChildSize: 0.3, maxChildSize: 0.9, expand: true, builder: (BuildContext context, ScrollController scrollController) => Container( decoration: Border-radius: borderRadius. Only (topLeft: Radius. Circular (16.0), topRight: Radius. Circular (16.0)), Child: _listWid(scrollController)));Copy the code
4. expand
Expand is used to determine whether to fill the parent Widget. If the outer layer of DraggableScrollableSheet is fixed in height, it will not be affected. Expand is used to fill the parent Widget if the outer layer is not fixed in height. The source code for the construct is also populated by SizedBox. Expand for the parent Widget;
return widget.expand ? SizedBox.expand(child: sheet) : sheet;
Copy the code
A small extension
In the previous analysis of DraggableScrollableSheet, its source code used FractionallySizedBox scale container, a small dish to briefly understand, its source code is very simple, You can set the ratio of heightFactor and widthFactor to the parent Widget. You can set the alignment mode of the parent Widget by using the alignment.
SizedBox. Expand (Child: _sizedBox()) _sizedBox() => FractionallySizedBox(heightFactor: 0.5, widthFactor: Child: 0.5, alignment, alignment, center, the Container (color: Colors. DeepOrange. WithOpacity (0.4), the child: ListView.builder( itemCount: 15, itemBuilder: (BuildContext context, index) => ListTile(title: Text('Current Item = ${(index + 1)}')))));Copy the code
Example source code
Xiao CAI is not familiar with the gesture sliding process of DraggableScrollableSheet, and will further learn the gesture later. If there are mistakes, please give more guidance!
Source: Little Monk A Ce