..
押すだけタイマー をつくる(3)
当たり前だが、リロードせずにリストに反映したい。
まずは、コントローラーにChangeNotifierを追加する。これで、以下のようになった。
preset_controller.dart
import 'package:flutter/material.dart';
import 'package:uuid/uuid.dart';
import 'preset.dart';
import 'preset_service.dart';
class PresetController with ChangeNotifier {
PresetController(this._presetService);
final PresetService _presetService;
late Map<String, Preset> _presets;
List<Preset> list() {
final List<Preset> _list = [];
_presets.forEach((key, value) {
_list.add(value);
});
return _list;
}
Future<void> loadPresets() async {
_presets = await _presetService.load();
notifyListeners();
}
Preset newPreset() {
const uuid = Uuid();
return Preset(uuid.v4());
}
Future<void> updatePreset(Preset preset) async {
_presets[preset.id] = preset;
notifyListeners();
await _presetService.update(preset);
}
}
それから、ListViewにAnimatedBuilderを使おう。
preset_list_view.dart
@override
Widget build(BuildContext context) {
var items = controller.list();
return AnimatedBuilder(
animation: controller,
builder: (context, child) {
return Scaffold(
これだと、リストが再構築されない。AnimatedBuilderのbuilder以下が再構築されるとして、そのリストの内容はAnimatedBuilder以前に取得している。これが原因なのだろうか。
Scaffold以下を別のWidgetにして、そのbuild関数内でリスト内容を取得すれば、再構築されるようになった。
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: controller,
builder: (context, child) {
return MainWidget(controller: controller);
},
);
}
class MainWidget extends StatelessWidget {
const MainWidget({
Key? key,
required this.controller,
}) : super(key: key);
final PresetController controller;
@override
Widget build(BuildContext context) {
var items = controller.list();
return Scaffold(
スケルトンは多言語対応しているので、保存ボタンでも、この仕組みを使おう。 app_en.arb
{
"appTitle": "One Touch Timer",
"@appTitle": {
"description": "The title of the application"
},
"save": "save"
}
app_ja.arb
{
"@@locale": "ja",
"appTitle": "押すだけタイマー",
"save": "保存する"
}
preset_details_view.dart
child: Text(
AppLocalizations.of(context)!.save,
)