[Flutter][Dart] List型のデータを渡して画面遷移(StatefulWidget側へ)する方法

データを渡して画面遷移する方法として、下記を参考に実装したら実現できた。
https://hiyoko-programming.com/1347/

String型あるいはInt型で渡すケースが多いと思うが、
リスト型の場合はどうやって渡したらいいんだろう？ということで自分なりに改良してみました。
結果、リスト型でも渡すことができたので以下に載せる。

## 環境
- macOS Monterey 11.3.1
- Flutter 3.3.1
- Dart 2.18.0

## まず、コードの中でも肝の部分。
### 画面遷移元
List型の alphabetsを引数に指定する際、実体を渡すためにList.of()を使って画面遷移先にデータを渡してあげる。

```dart
Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) => SelectTypes(checkList: List.of(alphabets)),
  ),
);
```

### 画面遷移先
画面遷移元からのList型データを受け取る変数と引数付きコンストラクタを用意、
受け取ったデータは、widget.変数名の形で使用。
さらに、画面遷移元から受け取ったデータを StatefulWidget の状態を管理する変数に
格納したい場合は、initState() 内で行うが、それもList型で指定。
```dart
class SelectTypes extends StatefulWidget {
  final List<String>  checkList;
  const SelectTypes({Key? key, required this.checkList}) : super(key: key);
  @override
  State<SelectTypes> createState() => _SelectTypesState();
}

class _SelectTypesState extends State<SelectTypes> {
  late List<String> state;
  @override
  void initState() {
    super.initState();
    state = widget.checkList;
  }
  … 省略
```

## デモとコードの紹介
### デモ
A,B,E,H,I を選択して「次へ」をフリック（A,B,E,H,Iはリスト型変数に追加）
<img width="300" alt="スクリーンショット 2022-10-10 0.07.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98081/d09e7b5f-4b12-c9af-e0aa-d2635d47057e.png">

選択したアルファベットを渡して画面遷移、画面遷移先でちゃんと値を受け取っていることがわかる。
<img width="300" alt="スクリーンショット 2022-10-10 0.07.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98081/8e764316-5b11-8929-cc46-9c7e2485a288.png">

### コードの紹介

main.dart
```dart
import 'package:flutter/material.dart';
import 'package:testapp/pages/keys.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: SelectKeys(),
    );
  }
}
```

```dart
import 'package:flutter/material.dart';
import 'package:testapp/pages/types.dart';

class SelectKeys extends StatefulWidget {
   const SelectKeys({Key? key}) : super(key: key);

  @override
  State<SelectKeys> createState() => _SelectKeysState();
}

class _SelectKeysState extends State<SelectKeys> {
  // 12keysを記載
  final keys = [
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
  ];
  var alphabets = <String>[];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
          title: const Text('Please select alphabet')
      ),
      body: Padding(
        padding: const EdgeInsets.all(30),
        child: Column(
          children: [
            Wrap(
              runSpacing: 16,
              spacing: 16,
              children: keys.map((key) {
                // keyが選択されているかどうかをListのcontainsメソッドを使って調べる
                final isSelected = alphabets.contains(key);
                return InkWell(
                  borderRadius: const BorderRadius.all(Radius.circular(32)),
                  onTap: () {
                    if (isSelected) {
                      // すでに選択されていれば取り除く
                      alphabets.remove(key);
                    } else {
                      // 選択されていなければ追加する
                      alphabets.add(key);
                    }
                    setState(() {});
                  },
                  child: AnimatedContainer(
                    duration: const Duration(milliseconds: 200),
                    padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
                    decoration: BoxDecoration(
                      borderRadius: const BorderRadius.all(Radius.circular(32)),
                      border: Border.all(
                        width: 2,
                        color: Colors.pink,
                      ),
                      color: isSelected ? Colors.pink : null,
                    ),
                    child: Text(
                      key,
                      style: TextStyle(
                        color: isSelected ? Colors.white : Colors.pink,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  ),
                );
              }).toList(),
            ),
            Expanded(
              child: Center(
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    ElevatedButton(
                      onPressed: () {
                        alphabets.clear();
                        setState(() {});
                      },
                      child: const Text('クリア'),
                    ),
                    const SizedBox(width: 16),
                    ElevatedButton(
                      onPressed: () {
                        // deep copy する方法
                        // selectedTags = tags だと参照を渡したことにしかならない
                        alphabets = List.of(keys);
                        setState(() {});
                      },
                      child: const Text('全て選択'),
                    ),
                    const SizedBox(width: 16),
                    ElevatedButton(
                        onPressed: () {
                          Navigator.push(
                            context,
                            MaterialPageRoute(
                                builder: (context) => SelectTypes(checkList: List.of(alphabets)),
                            ),
                          );
                        },
                        child: const Text("次へ"),
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
```

```dart
import 'package:flutter/material.dart';

class SelectTypes extends StatefulWidget {
  final List<String>  checkList;
  const SelectTypes({Key? key, required this.checkList}) : super(key: key);
  @override
  State<SelectTypes> createState() => _SelectTypesState();
}

class _SelectTypesState extends State<SelectTypes> {
  late List<String> state;
  @override
  void initState() {
    super.initState();
    state = widget.checkList;
  }

  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: const Text("確認")
      ),
      body: Center(
        child: Column(
          children: [
            for (final alphabet in state)
              Text(
                alphabet,
                style: const TextStyle(
                  fontSize: 30
                ),
              ),
          ],
        ),
      ),
    );
  }
}

```