Flutter:onClose的CupertinoPicker BottomSheet监听器?

Sim*_*mon 3 flutter bottom-sheet cupertinopicker

我正在通过Flutter Gallery查看与CupertinoPicker相关的代码.

这是相关的代码提取:

        child: new GestureDetector(
          // Blocks taps from propagating to the modal sheet and popping.
//          onTap: () { },
          child: new SafeArea(
            child: new CupertinoPicker(
              scrollController: scrollController,
              itemExtent: _kPickerItemHeight,
              backgroundColor: CupertinoColors.white,
              onSelectedItemChanged: (int index) {
                setState(() {
                  print(_selectedItemIndex);
                  _selectedItemIndex = index;
                });
              },
              children: new List<Widget>.generate(coolColorNames.length, (int index) {
                return new Center(child:
                  new Text(coolColorNames[index]),
                );
              }),
            ),
          ),
        ),
Run Code Online (Sandbox Code Playgroud)

现在,我需要一个回调/监听器,当CupertinoPicker关闭时,换句话说,当用户做出选择并且他的选择是最终的时候,我需要知道他的最终选择是什么.

这里的用例是我想在底片关闭时根据他的最终选择进行api回调.

目前,由于只有onSelectedItemChanged的回调,因此我只能在用户旋转选择器时获取值.见下面的gif.

在此输入图像描述

我看到BottomSheet小部件有一个onClosing回调:https://docs.flutter.io/flutter/material/BottomSheet-class.html

但是我很困惑如何获得它的实例,因为Flutter Gallery样本使用以下代码调用底层,并且没有方法从代码中获取底层:

      new GestureDetector(
        onTap: () async {
          await showModalBottomSheet<void>(
            context: context,
            builder: (BuildContext context) {
              return _buildBottomPicker();
            },
          );
        },
        child: _buildMenu(),
      ),
Run Code Online (Sandbox Code Playgroud)

有谁知道我怎么能得到回调监听器?

编辑 - 基于Remi的解决方案,我在onTap回调中添加了Navigator.of(context).pop(value)代码.但是,CupertinoPicker不是持久的,因此如果用户触摸选择器外部,选择器会自行解除并返回null值:

  Widget _buildBottomPicker() {
    final FixedExtentScrollController scrollController =
        new FixedExtentScrollController(initialItem: _selectedItemIndex);

    return new Container(
      height: _kPickerSheetHeight,
      color: CupertinoColors.white,
      child: new DefaultTextStyle(
        style: const TextStyle(
          color: CupertinoColors.black,
          fontSize: 22.0,
        ),
        child: new GestureDetector(
          // Blocks taps from propagating to the modal sheet and popping.
          onTap: () { Navigator.of(context).pop(_selectedItemIndex);},
          child: new SafeArea(
            child: new CupertinoPicker(
              scrollController: scrollController,
              itemExtent: _kPickerItemHeight,
              backgroundColor: CupertinoColors.white,
              onSelectedItemChanged: (int index) {
                setState(() {
//                  print(_selectedItemIndex);
//                  Navigator.of(context).pop(index);
                  _selectedItemIndex = index;
                });
              },
              children: new List<Widget>.generate(coolColorNames.length, (int index) {
                return new Center(child:
                  new Text(coolColorNames[index]),
                );
              }),
            ),
          ),
        ),
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)

Rém*_*let 13

它实际上比你想象的要简单得多.

showDialog并且它的对应物(包括showModalBottomSheet)返回Future包含结果的a.所以你可以做到以下几点:

final selectedId = await showModalBottomSheet<int>(...);
Run Code Online (Sandbox Code Playgroud)

唯一的要求是,在弹出模态/对话框/路由/任何内容时,您Navigator.of(context).pop(value)可以发送该值.