はじめに
例えばこんなModelがあったとき。
class Article {
const Article({
required this.title,
required this.description,
required this.type,
});
final String title;
final String description;
final ArticleType type;
}
enum ArticleType {
news, // ニュース
sport, // スポーツ
entertainment, // エンタメ
fashion, // ファッション
anime, // アニメ
}
enumからStringを取得したい
UIで、 ArticleType
によってその ArticleType
名を表示したくなったとします。
そのとき、以下のようなenumのextensionを用意してあげます。
extension ArticleTypeExt on ArticleType {
String get name {
switch (this) {
case ArticleType.news:
return 'ニュース';
case ArticleType.sport:
return 'スポーツ';
case ArticleType.entertainment:
return 'エンタメ';
case ArticleType.fashion:
return 'ファッション';
case ArticleType.anime:
return 'アニメ';
}
}
}
そうすることで、Widget側で以下のようなArticle
一覧を持っていた場合。
final articles = [
Article(title: 'タイトル1', description: '詳細1', type: ArticleType.anime),
Article(title: 'タイトル2', description: '詳細2', type: ArticleType.anime),
Article(title: 'タイトル3', description: '詳細3', type: ArticleType.anime),
];
こんな感じでenumのextensionを使ってArticleType
によって欲しい ArticleType
名を表示できます。
final articleTypeName = articles.first.type.name; // アニメ
enumからWidgetを取得したい
そして、articles
で以下のような記事一覧画面を作るとします。
return MaterialApp(
title: 'Flutter Demo',
home: ListView.builder(
padding: const EdgeInsets.all(8),
itemCount: articles.length,
itemBuilder: (BuildContext context, int index) {
final article = articles[index];
return Column(
children: [
Text(article.title),
Text(article.description),
],
);
},
),
);
そこで、article.type
によってリストのアイテムの中に表示する記事タグバッジWidgetみたいなものを出し分けたいときはこんな感じのWidgetを返すgetterを追加で書いてあげたらよさそうです。
extension ArticleTypeExt on ArticleType {
String get name {
switch (this) {
case ArticleType.news:
return 'ニュース';
case ArticleType.sport:
return 'スポーツ';
case ArticleType.entertainment:
return 'エンタメ';
case ArticleType.fashion:
return 'ファッション';
case ArticleType.anime:
return 'アニメ';
}
}
// ↓追加
Widget get tagBadge {
switch (this) {
case ArticleType.news:
return Container(); // ニュースのときのタグバッジ
case ArticleType.sport:
return Container(); // スポーツのときのタグバッジ
case ArticleType.entertainment:
return Container(); // エンタメのときのタグバッジ
case ArticleType.fashion:
return Container(); // ファッションのときのタグバッジ
case ArticleType.anime:
return Container(); // アニメのときのタグバッジ
}
}
}
使うときは、 article.type.tagBadge
するだけで ArticleType
ごとの欲しいWidgetを取得できてシュッとかけます。
return MaterialApp(
title: 'Flutter Demo',
home: ListView.builder(
padding: const EdgeInsets.all(8),
itemCount: articles.length,
itemBuilder: (BuildContext context, int index) {
final article = articles[index];
return Column(
children: [
Text(article.title),
Text(article.description),
article.type.tagBadge, // 追記:ArticleTypeごとのタグバッジWidget
],
);
},
),
);
privateでenumのextensionを定義したい
そのファイル内でしか使わないので、extensionを外に公開したくない場合は以下のように書けばprivateになります。extension名を省略するだけです。
extension on ArticleType {
String get name {
switch (this) {
case ArticleType.news:
return 'ニュース';
case ArticleType.sport:
return 'スポーツ';
case ArticleType.entertainment:
return 'エンタメ';
case ArticleType.fashion:
return 'ファッション';
case ArticleType.anime:
return 'アニメ';
}
}
}
extension内でメソッド定義
extension内でgetter以外に、なにか他のパラメータを使って値を返したいときはextension内でメソッド定義すればよいです。いい例が思いつかなかったですが、以下のようにあるパラメータを使って値を返すことができます。
extension on ArticleType {
String name(int articleCount) {
switch (this) {
case ArticleType.news:
return 'ニュース($articleCount)';
case ArticleType.sport:
return 'スポーツ($articleCount)';
case ArticleType.entertainment:
return 'エンタメ($articleCount)';
case ArticleType.fashion:
return 'ファッション($articleCount)';
case ArticleType.anime:
return 'アニメ($articleCount)';
}
}
}
おわり
地味に使うDartのenum extensionの便利な書き方と使い方を紹介しました。
これで少しDartが好きになりました。