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.

  1. showModalBottomSheet => Like a Dialog, not a part of Scaffold

  2. showBottomSheet => Part of Scaffold, 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:

enter image description here


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:

enter image description here