押すだけタイマー をつくる(4)
presetに名称を付けられるようにしよう。
まず、Presetにプロパティを追加する。変更可能なプロパティを追加したので、コンストラクタのconstは削除する必要がある。
preset.dart
class Preset {
Preset(this.id);
final String id;
String title = '';
}
つぎに、コントローラーにpresetを取得するための関数を追加する。該当idのpresetが存在しない場合は、新しいPresetを返却する。
preset_controller.dart
Preset getPreset(String id) {
var preset = _presets[id];
if (preset != null) {
return preset;
}
return Preset(id);
}
準備はできたので、いよいよ入力欄を追加する。まず、build関数内で、Presetを生成していたのを上記getPreset関数で取得するように変更する。
preset_details_view.dart
Preset preset = controller.getPreset(itemid);
つづけて、入力値を扱うためのTextEditingControllerを用意する。初期値には、presetのtitleをつかう。
var titleController = TextEditingController(text: preset.title);
入力欄を追加し、追加ボタンが押されたときに、その入力値でpresetのtitleを更新するようにする。
children: [
TextField(
controller: titleController,
maxLength: 30,
decoration: InputDecoration(
hintText: AppLocalizations.of(context)!.titleHint,
),
),
ElevatedButton(
onPressed: () {
preset.title = titleController.text;
controller.updatePreset(preset);
Navigator.of(context).pop();
},
app_en.arbとapp_ja.arbに、titleHintでつかう文字列を追加しておく。
つぎは時間の入力だが、flutter_pickerというプラグインをつかおう。
Installingにあるように、pubspec.yamlに追記してpub getすると、なぜか、多言語対応のプラグインが見つからなくなった。
Target of URI doesn't exist: 'package:flutter_gen/gen_l10n/app_localizations.dart'.
The values in a const list literal must be constants.
Undefined name 'AppLocalizations'.
このエラーは、以下の記事にあるように、Dart Analysis Severを再起動すると解消された。
Target of URI doesn’t exist: …
うむ、よくわからない。
まず、Presetに分(minutes)と秒(seconds)のプロパティを追加する。 つぎに、PresetDetailsViewに、分と秒を表示する。そして、ここをタッチするとflutter_pickerをつかった入力画面表示できるようにする。
GestureDetector(
onTap: () => showPickerNumber(context, preset),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
preset.minutes.toString().padLeft(2, '0'),
style: Theme.of(context).textTheme.headline2,
),
Text(
':',
style: Theme.of(context).textTheme.headline2,
),
Text(
preset.seconds.toString().padLeft(2, '0'),
style: Theme.of(context).textTheme.headline2,
),
],
),
),
それから、flutter_pickerのサンプルを元に、showPickerNumber関数を追加しておく。分を99まで入力したいので、数値を選択できるサンプルを流用した。
showPickerNumber(BuildContext context, Preset preset) {
Picker(
adapter: NumberPickerAdapter(data: [
NumberPickerColumn(begin: 0, end: 99, initValue: preset.minutes),
NumberPickerColumn(begin: 0, end: 59, initValue: preset.seconds),
]),
delimiter: [
PickerDelimiter(
child: Container(
width: 30.0,
alignment: Alignment.center,
child: Icon(Icons.more_vert),
),
)
],
hideHeader: true,
title: Text(AppLocalizations.of(context)!.selectTime),
onConfirm: (Picker picker, List value) {
preset.setMinutes(value[0]);
preset.setSeconds(value[1]);
},
).showDialog(context);
}
あとは、多言語対応。
app_en.arbとapp_ja.arbに、selectTimeでつかう文字列を追加しておく。
flutter_picker自体も多言語対応しているので、app.dartにも以下のように追記しておく。
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
PickerLocalizationsDelegate.delegate, // 追加した
],
これで、分と秒も設定できるようになった。ただし、詳細画面ではリロードしないと反映されない。