🛡️

sealed classを探求する②

2024/09/18に公開

何度かやらないと見えてこないことがある

Dart3.0から追加されたsealed classは、switchと組み合わせて使われることが多い。
例を出すと例外処理、Widgetの切り替えでしょうか🤔

official

Stateを更新してWidgetを切り替えるロジックを作ってみた。何度作るのか...
今回はgetterを2個クラスに定義した。

import 'package:flutter/material.dart';

// 都道府県を表すシールドクラス
sealed class Prefecture {
  String get name;
  String get capital;
}

// 各都道府県のクラス(一部のみ表示)
class Hokkaido extends Prefecture {
   String get name => '北海道';
   String get capital => '札幌市';
}

class Aomori extends Prefecture {
   String get name => '青森県';
   String get capital => '青森市';
}

class Tokyo extends Prefecture {
   String get name => '東京都';
   String get capital => '東京';
}

class Osaka extends Prefecture {
   String get name => '大阪府';
   String get capital => '大阪市';
}

class Okinawa extends Prefecture {
   String get name => '沖縄県';
   String get capital => '那覇市';
}

// ... 他の42府県も同様に定義 ...

class PrefectureApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: PrefectureSelector(),
    );
  }
}

class PrefectureSelector extends StatefulWidget {
  
  _PrefectureSelectorState createState() => _PrefectureSelectorState();
}

class _PrefectureSelectorState extends State<PrefectureSelector> {
  Prefecture currentPrefecture = Hokkaido();

  Widget _buildPrefectureWidget(Prefecture prefecture) {
    return switch (prefecture) {
      Hokkaido() => _buildPrefectureInfo(
        prefecture,
        icon: Icons.ac_unit,
        famousFor: 'ラベンダー畑、スキーリゾート',
      ),
      Aomori() => _buildPrefectureInfo(
        prefecture,
        icon: Icons.apple,
        famousFor: 'リンゴ、ねぶた祭り',
      ),
      Tokyo() => _buildPrefectureInfo(
        prefecture,
        icon: Icons.location_city,
        famousFor: 'スカイツリー、渋谷スクランブル交差点',
      ),
      Osaka() => _buildPrefectureInfo(
        prefecture,
        icon: Icons.restaurant,
        famousFor: 'たこ焼き、大阪城',
      ),
      Okinawa() => _buildPrefectureInfo(
        prefecture,
        icon: Icons.beach_access,
        famousFor: '美しいビーチ、沖縄料理',
      ),
      // ... 他の府県も同様に処理 ...
    };
  }

  Widget _buildPrefectureInfo(Prefecture prefecture, {
    required IconData icon,
    required String famousFor,
  }) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Icon(icon, size: 80),
        Text(prefecture.name, style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
        Text('県庁所在地: ${prefecture.capital}'),
        Text('有名なもの: $famousFor'),
      ],
    );
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('都道府県情報')),
      body: Center(
        child: _buildPrefectureWidget(currentPrefecture),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.refresh),
        onPressed: () {
          setState(() {
            // ランダムに都道府県を変更(実際はもっと多くの選択肢から)
            currentPrefecture = [Hokkaido(), Aomori(), Tokyo(), Osaka(), Okinawa()][DateTime.now().second % 5];
          });
        },
      ),
    );
  }
}

void main() {
  runApp(PrefectureApp());
}

感想

enum + switchでなんとかなってるので、あまり有効活用できていない。他にも使えそうなロジックがあれば試してみたい。

Discussion