🦔
Flutterで過去の地震の震度を可視化する
概要
Flutterの勉強のため、マップ上に地震情報をアニメーション表示するアプリを作成しました。
学習記録を残します。
成果物
GitHub
がんばったところ
Provider
地震情報、タイマーの値、マップのマーカーの値など、Widgetをまたぐ動的な値はすべてProviderで管理しました。
/// <<<Providerの定義>>>
// タイムシークの現在の値(インデックス)
class CurrentYearMonthIndexNotifier extends StateNotifier<int> {
CurrentYearMonthIndexNotifier() : super(0);
// 直接値を変える
void set(int index) {
state = index;
}
// 1づつ増やす
void increment() {
state = state + 1;
}
}
final currentYearMonthIndexProvider =
StateNotifierProvider<CurrentYearMonthIndexNotifier, int>((ref) {
return CurrentYearMonthIndexNotifier();
});
/// <<<利用シーン>>>
ref.read(currentYearMonthIndexProvider.notifier).increment();
Freezed
地震情報をJSONで保管しており、JSONデータをFlutterのクラスとして使うため、freezedを使用しました。
EarthquakeクラスのfromJson()
でJSON→クラスへの変換を行っています。
Earthquake.dart
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter/foundation.dart';
import "package:intl/intl.dart";
part 'earthquake.freezed.dart';
part 'earthquake.g.dart';
class Earthquake with _$Earthquake {
const factory Earthquake({
required String id,
required int depth,
required double latitude,
required double longitude,
required double magnitude,
required String place,
required int maxScale,
() required DateTime time,
}) = _Earthquake;
factory Earthquake.fromJson(Map<String, Object?> json) =>
_$EarthquakeFromJson(json);
}
class DateTimeConverter implements JsonConverter<DateTime, String> {
const DateTimeConverter();
DateTime fromJson(String json) {
try {
return DateTime.parse(json);
} catch (e) {
// 不正な形式の場合のエラーハンドリング
print('Failed to parse DateTime: $json, Error: $e');
throw FormatException('Invalid DateTime format', json);
}
}
String toJson(DateTime object) {
return object.toIso8601String();
}
}
earthquake_sevice.dart
class EarthquakeData {
static DateTime? firstDate;
static DateTime? lastDate;
static List<List<Earthquake>> earthquakes = [];
}
// 地震データを読み込み、EarthquakeDataへ保管
Future<void> loadJsonAsset() async {
try {
// jsonからデータ取得
String contents =
await rootBundle.loadString('assets/earthquake_data.json');
var jsonData = json.decode(contents);
var data = jsonData["data"];
List<List<Earthquake>> monthGroupEarthquakes = [];
// 年月でグループ化された地震情報を格納
for (List earthquakesJson in data) {
List<Earthquake> earthquakes = earthquakesJson.map((item) {
Map<String, Object?> earthquakeJson = {
"id": item["id"],
"depth": item["earthquake"]["depth"],
"latitude": item["earthquake"]["latitude"],
"longitude": item["earthquake"]["longitude"],
"magnitude": item["earthquake"]["magnitude"],
"place": item["earthquake"]["name"],
"maxScale": item["maxScale"],
"time": item["time"],
};
return Earthquake.fromJson(earthquakeJson);
}).toList();
monthGroupEarthquakes.add(earthquakes);
}
// EarthquakeDataクラスに格納
EarthquakeData.earthquakes = monthGroupEarthquakes;
EarthquakeData.firstDate = DateTime.parse(jsonData["first_date"]);
EarthquakeData.lastDate = DateTime.parse(jsonData["last_date"]);
} catch (e) {
print('Error loading JSON data: $e');
}
}
便利なパッケージたち
flutter_screenutil
画面とフォントサイズを適応させるためのFlutterプラグイン。
どの画面サイズでも、同じレイアウトで表示されます。
flutter_map
Mapを表示します。デモ、ドキュメントが充実しており、おすすめ。
Flutter学習中の所感
コード量多くないか?
Widgetをひたすら囲む特性上、改行が多くなり、逆に読みづらい気がする。。。
何かコツが必要なのかもしれない。
Discussion