添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I have a showModalBottomSheet like the below, which I understand to inherit from BottomSheet (right?)

      showModalBottomSheet<void>(
        context: context,
        builder: (BuildContext context) {
          return Container(
            height: 260.0,
            child: Text('I am text')

What I want to do:

I want to know (listen) when the modal is being closed, and act on it.

I've seen this onClosing callback: https://docs.flutter.io/flutter/material/BottomSheet/onClosing.html

How can I have a listener attached to the showModalBottomSheet, and then act accordingly when it fires?

You can also achieve it by use of whenComplete function of showModalBottomSheet.

Let's see below code

showModalBottomSheet<void>(
        context: context,
        builder: (BuildContext context) {
          return Container(
            height: 260.0,
            child: Text('I am text')
).whenComplete(() {
  print('Hey there, I\'m calling after hide bottomSheet');
                Note that whenComplete() fires as soon as the close action begins -- the widget tree has not yet been torn down yet (so you can't call dispose() methods in here for controllers, etc.) -- put only StatefulWidget instances in a bottom sheet, and override dispose(), if you want to run code when the widget tree is torn down after the close action is complete.
– Luke Hutchison
                Feb 24 at 2:32

Perhaps it's not the best solution, but showModalBottomSheet return a "Future" so you can used it.

For example:

void _showModal() {
    Future<void> future = showModalBottomSheet<void>(
      context: context,
      builder: (BuildContext context) {
        return Container(height: 260.0, child: Text('I am text'));
    future.then((void value) => _closeModal(value));
void _closeModal(void value) {
    print('modal closed');

Using async / await on showModalBottomSheet() close

You can do this with async / await instead of callbacks.

As per the documentation, showModalBottomSheet()

Returns a Future that resolves to the value (if any) that was passed to Navigator.pop when the modal bottom sheet was closed.

This means that we can "await" the showModelBottomSheet() to complete, and then use the value returned by the Navigator.pop() function used to close the sheet.

Because this is "waiting" for the sheet to be closed, your next function won't run until it's closed. In this example, we just call the print() function, but that could be any function you need. No callbacks are necessary in this case.

Tip: if it's critical that the user tap a "save and close" button to close the bottom sheet (instead of just tapping outside of it), you should use isDismissibile: false on the sheet.

In this example, we expect the sheet to return a string when it's closed.

Example Button To Open The showModalBottomSheet()

  FlatButton(
    child: Text("Show Bottom Sheet"),
    onPressed: () async {
      print("Showing bottom sheet...");
      String test = await showModalBottomSheet<String>(
        context: context,
        isDismissible: false,
        builder: (context) => Widget(),
      print("Modal sheet closed with value: " + test);

Example Button To Close The sheet, inside Widget()

FlatButton(
  child: Text("Save and Close"),
  onPressed: () {
    print("Closing sheet.");
    Navigator.pop(context, "This string will be passed back to the parent",);

Example Log Outputs

flutter: Showing bottom sheet...
flutter: Closing sheet.
flutter: Modal sheet closed with value: This string will be passed back to the parent
                This should be the accepted answer, it explains how to use showModalBottomSheet() very well and using async / await is more elegant than callbacks.
– Giles Correia Morton
                Jun 20, 2020 at 12:31

This is tested and verified on 28-01-2021

showBottomSheet(
  backgroundColor: Colors.black.withOpacity(0.5),
  context: context,
  builder: (context) {
    return Container(//your sheet code here);      
).closed.whenComplete(() {
 //do whatever you want after closing the bottom sheet
                This is the easiest method for showBottomSheet I found, for people using showModalBottomSheet  ".closed" will not be available, but still they can use showModalBottomSheet().whenComplete(); instead. Happy coding :)
– Manoranjan
                Feb 18, 2021 at 12:12
                i meant when the modalbottomsheet is closed to pass a value to it ao it can be used in whenComplete. but there seems to be no feature for this.
– chitgoks
                Aug 14, 2021 at 10:24

showBottomSheet does not return a future, now it returns a PersistentBottomSheetController

  var _scaffoldKey = GlobalKey<ScaffoldState>();
  PersistentBottomSheetController persistentBottomSheetController;
 persistentBottomSheetController = _scaffoldKey.currentState.showBottomSheet<void>(
    (context)=>Container(
 persistentBottomSheetController.closed.then(_closeModal);
  void _closeModal(void value) {
    print('modal closed');
                this is correct but it never gets the value passed back from the navigator you can read more here github.com/flutter/flutter/issues/66837
– martinseal1987
                Jun 1, 2021 at 13:28

I personally think the accepted answer is not as sleek as it can be. A wiser idea is to do it native Dart way without any extra complexity:

() async {
      final result = await showModalBottomSheet(context: context, builder: (_) =>

It also works with Navigator.of(context).pushNamed(). result variable value in my case is defined by the value you pass back on Navigator.of(context).pop({value}). You can return any kind of object and then make a simple if statement to make sure data is the one you want:

if(result != null && result == true) { ... }
                I would be really interested in why this was downvoted twice. For me this seems like the cleanest approach of them all. But I'm new to Dart and Flutter so would really like to understand if there is something wrong here.
– Hardcore_Graverobber
                May 8, 2020 at 9:40
                @Hardcore_Graverobber This IS the most idiomatic way to do it in Dart. I really don't know why my answer has -2 rep :D
– egorikem
                May 8, 2020 at 12:38
                I don't know whether the Future returned by showModalBottomSheet can ever result in an error, but in general you are going to want to use the following instead, which acts more like finally, so it always runs, even if the Future resolves to an error: showBottomSheet(...).whenComplete(() {...}). For example, this would be important if in whenComplete, you need to dispose of a controller or listener.
– Luke Hutchison
                Feb 23 at 23:21

The showBottomSheet return a future. Future<T?> showModalBottomSheet({});

So we can use a bool variable to check and know if the showBottomsheet is still open or not. For example, you have this code with this bool isStillOpen define in the top of your code,

Future<void> openShowBottomSheet(BuildContext  ctext) async {
// set your variable and open your bottomSheet
isStillOpen = true;
await showModalBottomSheet<void>(
  context: ctext,
  builder: (BuildContext context) =>
      Container(height: 300, child: Center(child: Text('Hello'))));
isStillOpen = false;

// when the showBotom is close, the variable isStillOpen is set to false, so anywhere in your code you can check your variable to know if the bottomSheet is open or not. var bottomSheet = showModalBottomSheet( context: context, builder: (context) => Container(); // Detect when it closes await bottomSheet.then((onValue) { print("value: $onValue"); // Do something here

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.