🐳

[Flutter]CupertinoPickerでiOS風ドラムロール式のPickerを実装

5 min read

こんにちは、daisukeです。😉

今回はCupertinoPicker Widget(以下、「Picker」)をご紹介します。
間違っていた場合はコメントで指摘していただけると幸いです。

完成図

リスト作成

まずはPickerに載せるリストと変数を用意します。
今回はnumbars、genders、iconsの3つを用意しました。

  final numbars = List<String>.generate(99, (index) => '$index');
  final genders = <String>['男', '女', 'その他'];
  final icons = <IconData>[
    Icons.ac_unit,
    Icons.access_alarm,
    Icons.account_box,
    Icons.settings,
    Icons.home,
    Icons.account_circle
  ];
// ↓にPickerで選択したアイテムが代入される予定です。
  String selectNumbar = '1';
  String selectGender = '男';
IconData selectIcon = Icons.ac_unit;

単体のリストをPicker上に表示

CupertinoPickerを呼び出すメゾッドを実装します。
まずは作成したnumbarsリストをPickerに表示させます。

import 'package:flutter/cupertino.dart';
void _cupertinoPicker() {
    showCupertinoModalPopup(
        context: context,
        builder: (context) {
          return Container(
	  //Pickerの高さを指定。指定しない場合はフルスクリーン。
            height: 250,
            color: Colors.white,
            child: Column(
              children: [
                TextButton(
                  child: const Text('閉じる'),
                  onPressed: () => Navigator.of(context).pop(),
                ),
                const Divider(),
                Expanded(
                  child: CupertinoPicker(
		 // ループさせるかどうか
                    looping: true,
		 // Pickerのそれぞれの高さ
                    itemExtent: 30,
		//先程作成したnumbarsリストをText Widgetに変換して読み込み。
                    children: numbars.map((numbar) => new Text(numbar)).toList(),
		//Pickerの操作を行う度に呼び出し。
		//selectNumbarに選択したnumbarsを代入。
                    onSelectedItemChanged: (index) {
                      setState(() {
                        selectNumbar = numbars[index];
                      });
                    },

                  ),
                ),
              ],
            ),
          );
        });
  }

複数のリストをPicker上に表示


numbarsに加え、同じ要領でgendersiconsをPicker上に表示させます。

void _cupertinoPicker() {
    showCupertinoModalPopup(
        context: context,
        builder: (context) {
          return Container(
            height: 250,
            color: Colors.white,
            child: Column(
              children: [
                TextButton(
                  child: const Text('閉じる'),
                  onPressed: () => Navigator.of(context).pop(),
                ),
                const Divider(),
                Expanded(
                  child: Row(
                    children: [
                      Expanded(
                        child: CupertinoPicker(
                          looping: true,
                          itemExtent: 30,
                          scrollController:
                              FixedExtentScrollController(initialItem: 0),
                          onSelectedItemChanged: (index) {
                            setState(() {
                              selectNumbar = numbars[index];
                            });
                          },
                          children: numbars
                              .map((numbar) => new Text(numbar))
                              .toList(),
                        ),
                      ),
                      Expanded(
                        child: CupertinoPicker(
                          itemExtent: 30,
                          scrollController:
                              FixedExtentScrollController(initialItem: 0),
                          onSelectedItemChanged: (index) {
                            setState(() {
                              selectGender = genders[index];
                            });
                          },
                          children: genders
                              .map((gender) => new Text(gender))
                              .toList(),
                        ),
                      ),
                      Expanded(
                        child: CupertinoPicker(
                          looping: true,
                          itemExtent: 30,
                          scrollController:
                              FixedExtentScrollController(initialItem: 0),
                          onSelectedItemChanged: (index) {
                            setState(() {
                              selectIcon = icons[index];
                            });
                          },
                          children:
                              icons.map((icon) => new Icon(icon)).toList(),
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          );
        });
  }

Pickerで選んだ結果を表示

      Row(
          children: <Widget>[
            Text(selectNumbar),
            Text(selectGender),
            Icon(selectIcon),
          ],
        ),

以上です。ご覧いただきありがとうございます!

https://github.com/tk-daisuke/cupertino_picker_example.git