LoginSignup
5

More than 3 years have passed since last update.

Flutterでタグ検索やフィルターを実装する(FilterChip)

Posted at

はじめに

こちらの記事はユアマイスターアドベントカレンダー2020、13日目の記事です。

動作イメージ

今回実装したのは、下記のように、都道府県を複数選択できるものです。
最初は、どのwidgetを使えばいいのかも分かりませんでした。
スクリーンショット 2020-12-12 17.51.46.png

実装

調べたところ、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(),
              ),
            ],
          ),
        ),
      );

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5