Close modal bottom sheet programmatically in flutter
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")
),
]),
);
});
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")
),
]),
);
});
Short answer:
Use any of the below:
Navigator.pop(context);
Navigator.of(context).pop();
Long answer:
Generally there are 2 types of bottom sheet.
-
showModalBottomSheet
=> Like aDialog
, not a part ofScaffold
-
showBottomSheet
=> Part ofScaffold
, this is persistent.
1. Showing and Hiding 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:
2. Showing and Hiding 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: