#はじめに
こちらの記事はユアマイスターアドベントカレンダー2020、13日目の記事です。
#動作イメージ
今回実装したのは、下記のように、都道府県を複数選択できるものです。
最初は、どのwidgetを使えばいいのかも分かりませんでした。
#実装
調べたところ、FilterChipを使えばよさそうでした。
https://api.flutter.dev/flutter/material/FilterChip-class.html
上記の公式ドキュメントにもある通り、Wrapを使うことで、自動で折り返しをしてくれるようです。
https://api.flutter.dev/flutter/widgets/Wrap-class.html
また、各地方ごとにListViewのItemとなるようにしています。
Region(地方モデル)は、nameとPrefecture(都道府県モデル)の配列を持っています。
class TestItem extends StatefulWidget {
/// constructors
const TestItem({
@required this.region,
Key key,
}) : assert(region != null, 'a must not be null'),
super(key: key);
final Region region;
@override
State<StatefulWidget> createState() => _TestItemState();
}
下記でFilterChipを作成します。
選択時の背景やテキスト、外枠の色や、チェックマーク非表示の設定もしています。
class _TestItemState extends State<TestItem> {
final List<int> _filters = <int>[];
Iterable<Widget> get prefectureWidgets sync* {
for (final prefecture in widget.region.prefectures) {
yield Padding(
padding: const EdgeInsets.all(4),
child: FilterChip(
label: Text(prefecture.name,
style: TextStyle(
color: _filters.contains(prefecture.prefectureCode)
? Colors.pink
: Colors.white)),
shape: RoundedRectangleBorder(
side: BorderSide(
color: _filters.contains(prefecture.prefectureCode)
? Colors.pink
: Colors.grey),
borderRadius: BorderRadius.circular(4)),
backgroundColor: Colors.white,
selectedColor: Colors.pink[50],
showCheckmark: false,
selected: _filters.contains(prefecture.prefectureCode),
onSelected: (value) {
setState(() {
if (value) {
_filters.add(prefecture.prefectureCode);
} else {
_filters.removeWhere((prefectureCode) =>
prefectureCode == prefecture.prefectureCode);
}
});
},
),
);
}
}
}
あとは表示をするだけです。
@override
Widget build(BuildContext context) => Ink(
color: Colors.white,
child: SafeArea(
top: false,
bottom: false,
minimum: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(widget.region.name),
Wrap(
children: prefectureWidgets.toList(),
),
],
),
),
);