データを渡して画面遷移する方法として、下記を参考に実装したら実現できた。
https://hiyoko-programming.com/1347/
String型あるいはInt型で渡すケースが多いと思うが、
リスト型の場合はどうやって渡したらいいんだろう?ということで自分なりに改良してみました。
結果、リスト型でも渡すことができたので以下に載せる。
環境
- macOS Monterey 11.3.1
- Flutter 3.3.1
- Dart 2.18.0
まず、コードの中でも肝の部分。
画面遷移元
List型の alphabetsを引数に指定する際、実体を渡すためにList.of()を使って画面遷移先にデータを渡してあげる。
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SelectTypes(checkList: List.of(alphabets)),
),
);
画面遷移先
画面遷移元からのList型データを受け取る変数と引数付きコンストラクタを用意、
受け取ったデータは、widget.変数名の形で使用。
さらに、画面遷移元から受け取ったデータを StatefulWidget の状態を管理する変数に
格納したい場合は、initState() 内で行うが、それもList型で指定。
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はリスト型変数に追加)
選択したアルファベットを渡して画面遷移、画面遷移先でちゃんと値を受け取っていることがわかる。
コードの紹介
main.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(),
);
}
}
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("次へ"),
),
],
),
),
),
],
),
),
);
}
}
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
),
),
],
),
),
);
}
}