showModalBottomSheet的Flutter onClosing回调

时间:2018-07-27 21:03:02

标签: dart flutter

我有一个类似下面的showModalBottomSheet,我知道它是从BottomSheet继承的(对吗?)

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

我想做什么:

我想知道(听)模态何时关闭并对其执行操作。

我看过这个onClosing回调: https://docs.flutter.io/flutter/material/BottomSheet/onClosing.html

如何在showModalBottomSheet上附加一个侦听器,然后在其触发时采取相应的行动?

8 个答案:

答案 0 :(得分:15)

在showModalBottomSheet()close上使用异步/等待

您可以使用async / await代替回调来完成此操作。

根据documentation,showModalBottomSheet()

返回一个Future,该Future解析为模式底部关闭时传递给Navigator.pop的值(如果有)。

这意味着我们可以“等待” showModelBottomSheet()完成,然后使用Navigator.pop()函数返回的值来关闭工作表。

由于这是“正在等待”工作表关闭,因此下一个功能要等到它关闭后才能运行。在此示例中,我们仅调用print()函数,但这可以是您需要的任何函数。在这种情况下,不需要回调。

提示:如果用户轻按“保存并关闭”按钮以关闭底部表单(而不是仅在其外部轻敲)非常重要,则应使用isDismissibile: false工作表。

在此示例中,我们希望工作表在关闭时返回一个字符串。

打开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);
    },
  ),

用于关闭工作表的示例按钮,位于Widget()

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

示例日志输出

flutter: Showing bottom sheet...
flutter: Closing sheet.
flutter: Modal sheet closed with value: This string will be passed back to the parent

答案 1 :(得分:5)

也许这不是最佳解决方案,但是showModalBottomSheet返回一个“ Future”,以便您可以使用它。

例如:

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');
}

答案 2 :(得分:4)

旧帖子,但无论如何,可能对您或其他人有帮助。因此,您也可以使用whenComplete的{​​{1}}函数来实现它。

让我们看下面的代码

showModalBottomSheet

就是这样。

答案 3 :(得分:4)

这是在 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
});

答案 4 :(得分:2)

showBottomSheet不返回未来,现在返回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');
  }

答案 5 :(得分:0)

() async {

   // Save the bottomsheet in a variable

   var bottomSheet = showModalBottomSheet(
      context: context,
      builder: (context) => Container();
    );

   // Detect when it closes
   await bottomSheet.then((onValue) {
     print("value: $onValue");
   });

   // Do something here
}

答案 6 :(得分:0)

WillPopScope小部件中的包装容器

showModalBottomSheet<void>(
        context: context,
        builder: (BuildContext context) {
          return WillPopScope(
            onWillPop: () aysnc{
              // listener dismiss
              return true;
            }
            child : Container(
              height: 260.0,
              child: Text('I am text')
            ));
        },
      );

答案 7 :(得分:-1)

我个人认为,已接受的答案并不那么流畅。一个更明智的想法是,以本机Dart方式进行操作,而无需任何额外的复杂性:

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

      );
}

它也可以与Navigator.of(context).pushNamed()一起使用。在我的情况下,result变量值由您在Navigator.of(context).pop({value})返回的值定义。您可以返回任何类型的对象,然后执行简单的if语句以确保数据是您想要的:

if(result != null && result == true) { ... }