Flutterで時間(時分秒)を入力するインターフェースの実装方法を調べたので軽く紹介します。

showTimePicker を使う

時間を入力する方法として最もメジャーなのが、showTimePicker()を使う方法だと思います。
ただし、showTimePicker()は、モーダルダイアログで時(hour)/分(minute)を入力してTimeOfDayを返す関数なので、秒(second)は入力できません。

デフォルト

デフォルトでは以下のようなUIになります。

個人的には、このデフォルトUIは、

  • 時(hour)を選んでいるのか分(minute)を選んでいるのか分かりにくい
  • 0時を選べない

というマイナスポイントがあると感じています。

該当部分の抜粋は以下の通りです(全文はこちら)。

TextButton(
  child: Text('edit', style: TextStyle(decoration: TextDecoration.underline)),
  onPressed: () async {
    final TimeOfDay timeOfDay = await showTimePicker(context: context, initialTime: _timeOfDay);
    if (timeOfDay != null) setState(() => {_timeOfDay = timeOfDay});
  },
),

ポイントは以下です。

  • editボタンをタップした際に、showTimePickerを呼び出す
  • awaitして同期的に結果を受け取る
  • 結果を変数に反映して、setState()で変更を画面に反映する

24時間制

24時間制で入力させることもできます。

該当部分の抜粋は以下の通りです(全文はこちら)。

TextButton(
  child: Text('edit', style: TextStyle(decoration: TextDecoration.underline)),
  onPressed: () async {
    final timeOfDay = await showTimePicker(
      context: context,
      initialTime: _timeOfDay,
      initialEntryMode: TimePickerEntryMode.input,
      builder: (BuildContext context, Widget child) {
        return MediaQuery(
          data: MediaQuery.of(context).copyWith(alwaysUse24HourFormat: true),
          child: child,
        );
      },
    );
    if (timeOfDay != null) setState(() => {_timeOfDay = timeOfDay});
  },
),

この例では、時間を直接入力するモードに変更した上で、24時間制になるようにしてみました。
以下二点をデフォルトから変更してます。

  • 直接入力モードにためにinitialEntryMode: TimePickerEntryMode.inputの設定を追加
  • builderalwaysUse24HourFormat: trueMediaQueryを設定

秒(second)まで入力できるようにしたい場合は、showTimePicker()では対応できないため、別の方法が必要です。時分秒をシンプルに入力するプラグインは発見できなかったので、FlutterPickerを使う方法が良さそうです。

FlutterPicker を使う

Flutter Picker は、ArrayNumberDateDateTimeなどを、セレクトするPickerを提供してくれるプラグインです。今回はDateTime型のPickerを利用します。

事前に、pubspec.yaml に以下の依存関係を追加する必要があります。

dependencies:
  flutter_picker: ^2.0.1

該当部分の抜粋は以下の通りです(全文はこちら)。

import 'package:flutter_picker/flutter_picker.dart';
TextButton(
  child: Text('edit', style: TextStyle(decoration: TextDecoration.underline)),
  onPressed: () async {
    Picker(
      adapter: DateTimePickerAdapter(type: PickerDateTimeType.kHMS, value: _datetime, customColumnType: [3, 4, 5]),
      title: Text("Select Time"),
      onConfirm: (Picker picker, List value) {
        setState(() => {_datetime = DateTime.utc(0, 0, 0, value[0], value[1], value[2])});
      },
    ).showModal(context);
  },
),

ポイントは以下です。

  • adaptertypePickerDateTimeType.kHMSを指定して、hh:mm:ssを入力するようにする
  • adaptercustomColumnType3(hour), 4(minute), 5(sec)を指定する
  • onConfirmで結果を取得して、_datetimeという変数に設定する