DropdownButtonを使って時刻を選択するサンプルを作りました。
引数に選択範囲の最小と最大を指定すると、その範囲内に限定した状態で選択できるようになります。
import 'package:flutter/material.dart';void main() => runApp(const MyApp());class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: Builder(builder: (context) { return Scaffold( appBar: AppBar( title: const Text('サンプル'), centerTitle: true, backgroundColor: Colors.green, ), body: Container( color: Colors.green.shade200, padding: const EdgeInsets.all(20.0), child: Center( child: ElevatedButton( child: const Text('時間を決める', style: TextStyle(fontSize: 30.0)), onPressed: () { showDialog( context: context, builder: (BuildContext context) => const TimePickerDialog( minTime: TimeOfDay(hour: 9, minute: 30), maxTime: TimeOfDay(hour: 24, minute: 0), )); }, ), ), ), ); }), ); }}class TimePickerDialog extends StatefulWidget { const TimePickerDialog( {Key? key, required this.minTime, required this.maxTime}) : super(key: key); final TimeOfDay minTime; final TimeOfDay maxTime; @override State<TimePickerDialog> createState() => _TimePickerDialogState();}class _TimePickerDialogState extends State<TimePickerDialog> { int hour = 0; int minute = 0; @override void initState() { hour = widget.minTime.hour; minute = widget.minTime.minute; super.initState(); } @override Widget build(BuildContext context) { return AlertDialog( title: const Text('時間を設定してください'), content: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ DropdownButton( items: selectableHours.map<DropdownMenuItem<int>>((int value) { return DropdownMenuItem<int>( value: value, child: Text( value.toString(), style: const TextStyle(fontSize: 30.0), ), ); }).toList(), value: hour, onChanged: (int? newValue) { setState(() { hour = newValue!; minute = selectableMinMinute; }); }), const Text( ':', style: TextStyle(fontSize: 30.0), ), DropdownButton( items: selectableMinutes.map<DropdownMenuItem<int>>((int value) { return DropdownMenuItem<int>( value: value, child: Text( value.toString(), style: const TextStyle(fontSize: 30.0), ), ); }).toList(), value: minute, onChanged: (int? newValue) { setState(() { minute = newValue!; }); }), ], ), actions: [ ElevatedButton( child: const Text('Cancel'), onPressed: () => Navigator.pop(context), ), ElevatedButton( child: const Text('OK'), onPressed: () { print('selected time is $hour:$minute'); }, ), ]); } List<int> get selectableHours { return List<int>.generate((widget.maxTime.hour - widget.minTime.hour + 1), (int index) => widget.minTime.hour + index); } int get selectableMinMinute { return widget.minTime.hour == hour ? widget.minTime.minute : 0; } int get selectableMaxMinute { return widget.maxTime.hour == hour ? widget.maxTime.minute : 59; } List<int> get selectableMinutes { return List<int>.generate((selectableMaxMinute - selectableMinMinute + 1), (int index) => selectableMinMinute + index); }}
Flutterだと、TimePickerというWidgetを呼び出す方法があります。
通常だとこちらの方が手軽で便利ですが、時刻の選択範囲が0から24時間という欠点があります。
例えば、25時(深夜1時)を選択できるようにしたい、みたいな要件があったときはTimePickerは使えません。
そうしたときはWidgetを駆使して自分で作らないといけないですね。
あとは、TimePickerのグルグルUIを採用したくないときも該当すると思います。
サンプルでは引数をTimeOfDayというFlutter組み込みのクラスで取り扱っていますが、実は25時以降を選べるようにしたいときはこのクラスは使えません。
引数の渡し方も独自に工夫する必要がありそうです。
*「Run」を押すと実行できます。