目前,我正在尝试开发一种BottomSheet扩展到特定大小的。当达到该大小时,用户应该可以将其BottomSheet向上拖动一点。我将插入了的GestureDetector内部BottomSheet,以便能够检测到垂直阻力。拖动函数被调用,但是不幸的是它没有改变的大小BottomSheet。
BottomSheet
GestureDetector
这是我的代码:
//These values are outside of the classes double initial; double _kShoppingMenuHeight; //My custom BottomSheet with rounded corner Future<T> showRoundedBottomSheet<T> ({ @required BuildContext context, @required Widget child, double height }) { assert(context != null); assert(child != null); return showModalBottomSheet( context: context, builder: (BuildContext context){ return new Container( height: (height != null ? height : 400.0 ), color: Color(0xFF737373), child: new Container( decoration: new BoxDecoration( color: Colors.white, borderRadius: new BorderRadius.only( topLeft: const Radius.circular(5.0), topRight: const Radius.circular(5.0) ) ), child: Builder( builder: (BuildContext context){ return child; }, ) ), ); } ); } //The function that opens the BottomSheet // this is in another class return showRoundedBottomSheet( context: context, height: _kShoppingMenuHeight, //Make bottomsheet draggable and fixed at specific point child: ShoppingMenu( title: _title("Ihre Listen"), items: items ) ); //The stateful widget with the content return GestureDetector( onVerticalDragStart: (DragStartDetails details){ initial = details.globalPosition.dy; }, onVerticalDragUpdate: (DragUpdateDetails details){ setState(() { _kShoppingMenuHeight = MediaQuery.of(context).size.height / 2 - details.globalPosition.dy; if(_kShoppingMenuHeight.isNegative) _kShoppingMenuHeight = _kShoppingMenuHeight * (-1); }); }, onVerticalDragEnd: (DragEndDetails details){ }, child: NotificationListener<OverscrollIndicatorNotification>( onNotification: (overscroll){ overscroll.disallowGlow(); }, child: ConstrainedBox( constraints: BoxConstraints( minHeight: _kShoppingMenuHeight ), child: ListView( physics: NeverScrollableScrollPhysics(), children: <Widget>[ Padding( padding: EdgeInsets.only(top: 30.0, left: 10.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Padding( padding: EdgeInsets.only(bottom: 10.0), child: widget.title, ), Column( children: widget.items ) ], ), ), Divider(), GestureDetector( child: ListTile( leading: Icon(Icons.add, color: Colors.black54), title: Text( "Neue Liste erstellen" ), ), onTap: (){ Navigator.pop(context, "neue Liste"); }, ), Divider(), GestureDetector( child: ListTile( leading: Icon(OMIcons.smsFailed, color: Colors.black54), title: Text( "Feedback geben" ), ), onTap: (){ Navigator.pop(context, "feedback"); }, ) ], ), ), ), );
这是如何拖动模态底部工作表的完整示例。
这个想法是由流构建器包装工作表的内容,并在发生拖动时更新流。让我知道您是否需要进一步的解释。
import 'package:flutter/material.dart'; import 'dart:async'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text('My App'), ), body: MyWidget(), ), ); } } StreamController<double> controller = StreamController.broadcast(); class MyWidget extends StatefulWidget{ @override _MyWidgetState createState() => _MyWidgetState(); } class _MyWidgetState extends State<MyWidget> { double position; @override Widget build(BuildContext context) { return Container( child: Center( child: RaisedButton( child: Text('Show Buttom Sheet'), onPressed: () { showModalBottomSheet(context: context, builder: (context){ return StreamBuilder( stream: controller.stream, builder:(context,snapshot) => GestureDetector( onVerticalDragUpdate: (DragUpdateDetails details){ position = MediaQuery.of(context).size.height- details.globalPosition.dy; print('position dy = ${position}'); position.isNegative?Navigator.pop(context) :controller.add(position); }, behavior: HitTestBehavior.translucent, child: Container( color: Colors.red, height: snapshot.hasData ? snapshot.data:200.0, width: double.infinity, child: Text('Child'), )), ); }); }), ), ); } }