【Flutter】ドロップダウンリストを実装してみよう

# やりたいこと
今回はドロップダウンリストを実装していきます。
このような見た目になるのが理想です。
![スクリーンショット 2022-08-15 13.41.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737303/65ed6d38-896b-5823-c409-153f4b13e9ce.png)


# 開発環境
* MacOS Monterey 12.4
* Android Studio
* Flutter 3.0.3
* Dart 2.17.6
# 実装方法
今回はパッケージのインポートは特に必要なく、widgetのみで作ることが可能です。
ドロップダウンリストの実装には、DropdownButtonウィジェットを使用します。

選択した値を変数に保存して表示する必要があるため、まず変数を定義します。
```php:main.dart
    String? isSelectedItem;
```

その上で見た目の記述に移ります。
DropdownButtunの中にDropdownMenuItemで選択肢を指定します。
このとき、childとvalue両方記述する必要があります。
```php:main.dart
    child: DropdownButton(
                items: const [
                  DropdownMenuItem(
                    child: Text('島根県'),
                    value: '島根県',
                  ),
                  DropdownMenuItem(
                    child: Text('鳥取県'),
                    value: '鳥取県',
                  ),
                  DropdownMenuItem(
                    child: Text('山口県'),
                    value: '山口県',
                  ),
                ],
             )
```

そして、onChangedしたときに値をsetStateすることで、選択した値を表示してあげることができます。
```php:main.dart
    onChanged: (String? value) {
                  setState(() {
                    isSelectedItem = value;
                  });
                  debugPrint(isSelectedItem);
                },
                value: isSelectedItem,
```

まとめると、こんな感じ。
ヒントテキストも指定できます。
```php:main.dart
    Container(
              margin: const EdgeInsets.only(top: 40),
              padding: const EdgeInsets.only(left: 80),
              width: 300,
              color: Colors.white,
              child: DropdownButton(
                hint: Text('選択してください'),
                items: const [
                  DropdownMenuItem(
                    child: Text('島根県'),
                    value: '島根県',
                  ),
                  DropdownMenuItem(
                    child: Text('鳥取県'),
                    value: '鳥取県',
                  ),
                  DropdownMenuItem(
                    child: Text('山口県'),
                    value: '山口県',
                  ),
                ],
                onChanged: (String? value) {
                  setState(() {
                    isSelectedItem = value;
                  });
                  debugPrint(isSelectedItem);
                },
                value: isSelectedItem,
              ),
            ),
```

そうすると、画面はこのような見た目になるはずです。
見づらいためbackgroundColorにgreenを指定しています。
![スクリーンショット 2022-08-15 13.52.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737303/df33f53f-a9c7-e7ae-f139-a63b315524c7.png)


# 実際の画面
値が選択できて、表示もできることがわかります。

http://www.giphy.com/gifs/6aFFEE6zPshmW5rZOd

別記事で紹介したshared_preferencesを使えば、選択した値の保存も可能です。
>https://qiita.com/yooooda/items/ebc4e8f6e42d900f3b5e

http://www.giphy.com/gifs/sv5bDQq0STEt5kiRl8


# おわりに
ドロップダウンリストは、入力フォームなどで使う機会があるかと思います。他のWidgetと組み合わせるとかなり幅が広がるのではないでしょうか。
この記事が参考になれば嬉しいです(￣▽￣)

# コード全文
```php:main.dart
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String? isSelectedItem2;
  static const keyTeam2 = 'team2';

  @override
  void initState() {
    super.initState();
    Future(() async {
      await _getData();
    });
  }

  //保存
  Future<void> _setData() async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(keyTeam2, isSelectedItem2!);
  }

  //読み込み
  Future<void> _getData() async {
    final prefs = await SharedPreferences.getInstance();
    setState(() {
      isSelectedItem2 = prefs.getString(keyTeam2); //キーに紐付けた値を変数に代入
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.green,
      appBar: AppBar(
        title: Text("ドロップダウンリスト"),
        centerTitle: true,
      ),
      body: Center(
        child: Column(
          children: [
            Container(
              margin: const EdgeInsets.only(top: 40),
              padding: const EdgeInsets.only(left: 80),
              width: 300,
              color: Colors.white,
              child: DropdownButton(
                hint: Text('選択してください'),
                items: const [
                  DropdownMenuItem(
                    child: Text('島根県'),
                    value: '島根県',
                  ),
                  DropdownMenuItem(
                    child: Text('鳥取県'),
                    value: '鳥取県',
                  ),
                  DropdownMenuItem(
                    child: Text('山口県'),
                    value: '山口県',
                  ),
                ],
                onChanged: (String? value) {
                  setState(() {
                    isSelectedItem2 = value;
                  });
                  debugPrint(isSelectedItem2);
                },
                value: isSelectedItem2,
              ),
            ),
            Container(
                margin: const EdgeInsets.only(top: 40),
                child: SizedBox(
                  width: 150,
                  height: 50,
                  child: ElevatedButton(
                    child: const Text('保存'),
                    style: ElevatedButton.styleFrom(
                      primary: Colors.orange,
                      onPrimary: Colors.white,
                    ),
                    onPressed: () {
                      _setData();
                      ScaffoldMessenger.of(context).showSnackBar(
                        SnackBar(
                          duration: const Duration(seconds: 5),
                          content: Text('保存しました'),
                          action: SnackBarAction(
                            label: '閉じる',
                            onPressed: () {},
                          ),
                        ),
                      );
                    },
                  ),
                )),
          ],
        ),
      ),
    );
  }
}

```