I am displaying a BottomSheet via showModalBottomSheet<Null>()
and inside several widgets with a GestureDetector. I would like to see the BottomSheet closed not only by touching outside it but also after an onTap event of a GestureDetector inside. However, it seems the GestureDetector is not forwarding the touch event.
So I am wondering, is there a way to trigger the closing of the ModalBottomSheet programmatically or a way to tell the GestureDetector to forward the touch event?
Update (2018-04-12):
Following a code snippet for better understanding. The problem is that the ModalBottomSheet isn't closing when tapping on "Item 1" or "Item 2".
showModalBottomSheet<Null>(context: context, builder: (BuildContext context) { return new SingleChildScrollView(child: new Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [ new GestureDetector(onTap: () { doSomething(); }, child: new Text("Item 1") ), new GestureDetector(onTap: () { doSomething(); }, child: new Text("Item 2") ), ]), ); });
Modal Bottom Sheet is an alternative to a menu or a dialog and prevents the user from interacting with the rest of the app. It will appear over the UI so that there is no need to navigate to a different page. It can be used to perform a small task that does not require the whole new screen to be built.
How To Display Bottom Sheet In Flutter ? To display a general bottom sheet we have to use bottomSheet property of scaffold widget. return Scaffold( appBar: AppBar( title: Text("Flutter Bottom Sheet"), ), body:Container(), bottomSheet: BottomSheet(), );
Calling bottomsheet. close() or pressing on the backdrop will close the bottom sheet completely.
Persistent : Persistent bottom sheet is a view which display over the current visible screen and remain visible at the time of interaction with user or at the time of user iteration. In Flutter we display persistent bottom sheet by using showBottomSheet function of Scaffold class.
Closing a ModalBottomSheet programmatically is done via
Navigator.pop(context);
So I just call that pop function inside the onTap callback function of the GestureDetector.
showModalBottomSheet(context: context, builder: (BuildContext context) { return SingleChildScrollView(child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [ GestureDetector(onTap: () { Navigator.pop(context); doSomething(); }, child: Text("Item 1") ), GestureDetector(onTap: () { Navigator.pop(context); doSomething(); }, child: Text("Item 2") ), ]), ); });
Use any of the below:
Navigator.pop(context); Navigator.of(context).pop();
Generally there are 2 types of bottom sheet.
showModalBottomSheet
=> Like a Dialog
, not a part of Scaffold
showBottomSheet
=> Part of Scaffold
, this is persistent.
showModalBottomSheet
This code shows bottom sheet, and hides it when tapping on the FlutterLogo
@override void initState() { super.initState(); Future(() { showModalBottomSheet( context: context, builder: (_) { return GestureDetector( onTap: () => Navigator.of(context).pop(), // Closing the sheet. child: FlutterLogo(size: 200), ); }, ); }); }
Output:
showBottomSheet
This code shows a button, which will open and close the bottom sheet.
late PersistentBottomSheetController _controller; GlobalKey<ScaffoldState> _key = GlobalKey(); bool _open = false; @override Widget build(BuildContext context) { return Scaffold( key: _key, body: Center( child: ElevatedButton( onPressed: () { if (!_open) { _controller = _key.currentState!.showBottomSheet( (_) => SizedBox( child: FlutterLogo(size: 200), width: double.maxFinite, ), ); } else { _controller.close(); } setState(() => _open = !_open); }, child: Text(_open ? "Close" : "Open"), ), ), ); }
Output:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With