Flutter-ドロップダウンボタン様式のFilterChip

Material 3のFilterChipでメニューを表示し項目を選択するというのがあるのだけど、FlutterのMaterialでは実装されていないようで、またパッケージ側を探してみたのだけどそちらもないようなので作ってみた。

FilterChipのメニュー物

Chips – Material Design 3
Chips help people enter information, make selections, filter content, or trigger actions. Chips can show multiple intera...

上のようなもの。

ちなみにChipのMaterial 3の追従はどうなっているかというと、Issuesには上げられている。

☂️ `Chip` does not conform to M3 specs · Issue #115364 · flutter/flutter
☂️ Material 3 Design Specification Issues with Chips While using and reviewing Material 3 Chips I noticed the following ...

仕様みたいなものと実装

メニュー選択式のFilterChipは、ポップアップメニュー内にLeadingなアイコンが表示されていて、ページ内の説明には書いていないが選択のキャンセルも可能なようなイメージをとらえている。
hintに関してはvalueがnullの時に表示するようにしている。

一応これらを使えるようにしたのが、以下のクラス。

Material 3のFilterChipに掲載されていたメニューから項目を選択できる機能を実装したもの
Material 3のFilterChipに掲載されていたメニューから項目を選択できる機能を実装したもの - selectable_filter_chip.dart

サンプルコードは以下の様な感じ。

enum RadioSelector { hoge, hage, dummy }

SelectableFilterChip<RadioSelector>(
  items: RadioSelector.values
      .map(
        (e) => DropdownMenuEntry<RadioSelector>(
          value: e,
          label: e.name,
          leadingIcon: const Icon(Icons.abc),
          trailingIcon: const Icon(Icons.access_alarm),
        ),
      )
      .toList(),
  value: _switch ? _radio : null,
  hint: const Text("Select"),
  onChanged: (value) {
    if (value != null) {
      setState(() {
        _radio = value;
        _switch = true;
      });
    }
  },
  onUnselected: () {
    setState(() {
      _switch = false;
    });
  },
)

enumの項目を選択可能にしている。
選択されているかどうかについては、_switchというboolのフラグで管理し、現在選択されているアイテムは_radioに格納している。

実際動かしたのが上の図になる。

実装部分のちょっとした説明

itemsの選択項目については、DropdownMenuEntryを使っている。
設定値、ラベル文字列、先頭・末尾に表示するウィジェット(アイコン)がもれなく設定できるので利用可能なのがこれしかなかったから。

Material 3のページを見た感じ、ポップアップされたメニュー項目にリーディングアイコンが設定されていたのだけど、Chipにはアイコンが表示されていないので、こういった形にした。

メニューの表示にはListTileを使っている。
大きさ等気に入らなかったら、その部分を辺こすると良いと思う。

ポップアップメニューはshowMenuで表示しているのだけど、その表示位置はChipの下側になるように調整している。

表示位置に関しては、キー経由でRenderObject の情報を引っ張ってきてそれを使っている。

コメント

タイトルとURLをコピーしました