6

CupertinoPicker に関連するコードを Flutter Gallery で探しています。

関連するコードの抜粋は次のとおりです。

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

ここで、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(),
      ),

これのコールバックリスナーを取得する方法を知っている人はいますか?

編集 - 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]),
                );
              }),
            ),
          ),
        ),
      ),
    );
  }
4

4 に答える 4