..

押すだけタイマー をつくる(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,
)