🚅

FlutterのDropdownButtonでタイトルを実装する

2023/12/02に公開

DropdownButtonでタイトルを実装する方法について解説します!

こんな感じのイメージ。

【北海道・東北】
 北海道
 青森県
 岩手県
 宮城県
 秋田県
 山形県
 福島県
【関東】
 茨城県
 栃木県
 群馬県
 埼玉県
 千葉県
 東京都
 神奈川県
 山梨県
 長野県

【】の部分がタイトルでここは選択不可。
他都道府県は選択可能の項目として実装します!

各要素分け

都道府県(日本語・英語)クラスを持ち、

○都道府県の表示クラス → PrefectureButtonItem : Prefecture
○タイトル項目表示クラス   → TitleItem : Prefecture
として実装します。それぞれPrefectureクラスを継承します。

/// 都道府県のクラス
class Prefecture {
  final String nameJa;
  final String nameEn;

  const Prefecture(this.nameJa, this.nameEn);
}

/// 都道府県の選択項目クラス
class PrefectureButtonItem extends Prefecture {
  PrefectureButtonItem(String nameJa, String nameEn) : super(nameJa, nameEn);
}

/// タイトル部分のクラス
class TitleItem extends Prefecture {
  Color backgroundColor;

  TitleItem(String nameJa, String nameEn, this.backgroundColor) : super(nameJa, nameEn);
}

都道府県の一覧作成

prefectureListをPrefectureのリストとして作成しますが、
上記の通りタイトル、都道府県と分けてそれぞれ入れます。

また選択中のアイテムはPrefectureButtonItemのみにしたいため、whereTypeで初期状態を制限します。

  // @formatter:off
  /// 都道府県リスト
  static List<Prefecture> prefectureList = [
    TitleItem('北海道・東北', 'Hokkaido/Tohoku', Colors.grey),
    PrefectureButtonItem('北海道', 'Hokkaido'),
    PrefectureButtonItem('青森県', 'Aomori'),
    PrefectureButtonItem('岩手県', 'Iwate'),
    PrefectureButtonItem('秋田県', 'Akita'),
    PrefectureButtonItem('山形県', 'Yamagata'),
    PrefectureButtonItem('福島県', 'Fukushima'),
    // 以降続く
  ];
  // @formatter:on

  // 選択中の都道府県
  Prefecture selectPrefecture =
      prefectureList.whereType<PrefectureButtonItem>().first;

各要素の実装

選択部分

選択項目部分は
左部にマージンを入れてタイトルに付随するのがわかるようにし、
それぞれにitemの要素を記載します。


// 都道府県の選択項目
DropdownMenuItem<Prefecture> selectItem(Prefecture item) {
  return DropdownMenuItem<Prefecture>(
      value: item,
      child: Container(
        margin: const EdgeInsets.only(left: 8), // 隙間入れる
        child: Text('${item.nameJa} ${item.nameEn}'),
      ));
}

タイトル部分

タイトル部分は押下不可に設定し、かつ今回は背景色を設定しています。
また選択可能な都道府県よりも小さく表示します。


// タイトル部分のアイテム
DropdownMenuItem<Prefecture> titleItem(TitleItem titleItem) {
  return DropdownMenuItem<Prefecture>(
    value: titleItem,
    enabled: false, // 押下不可
    child: Container(
      width: double.infinity,
      constraints: const BoxConstraints(minHeight: 32), // やや小
      color: titleItem.backgroundColor,
      child: Text('${titleItem.nameJa} ${titleItem.nameEn}'),
    ),
  );
}

実際にDropdownButonを実装している箇所になります。

itemsのパラメータにswitch文でそれぞれタイトル/選択項目を表示分けて実装します。


// 都道府県選択ボタン
DropdownButton<Prefecture>(
	isExpanded: true,
	value: selectPrefecture,
	items: prefectureList.map((Prefecture prefecture) {
	switch (prefecture) {
	  case PrefectureButtonItem():
	    return selectItem(prefecture);
	  case TitleItem():
	    return titleItem(prefecture);
	  default:
	    return selectItem(prefecture);
	}
	}).toList(),
	onChanged: (value) {
	setState(() {
	  selectPrefecture = value!;
	});
	},
)

動作確認

挙動はこんな感じ。

全体表示のパターン。

タイトル部分は押下不可が確認できると思います。

めでたしめでたし。

Arsaga Developers Blog

Discussion