How to Implement a Time Picker in Flutter: The Complete Mobile Guide
The most efficient way to implement a time picker in Flutter is to use the built-in showTimePicker function, which renders a high-performance Material Design TimePickerDialog optimized for mobile accessibility and theming.
The Flutter framework provides a comprehensive time selection solution within its Material library. For developers building mobile applications, implementing a time picker in Flutter requires understanding the showTimePicker API and its underlying TimePickerDialog implementation. According to the flutter/flutter source code, this approach ensures Material compliance while minimizing widget rebuilds and maintaining responsive UI performance.
Why showTimePicker Is the Recommended Approach
The showTimePicker function defined in packages/flutter/lib/src/material/time_picker.dart serves as the primary entry point for time selection. This method instantiates a TimePickerDialog and displays it via showDialog, providing several architectural advantages:
- Performance Optimization: The dialog builds once and leverages Flutter's native overlay system, preventing unnecessary repaints during time selection.
- Material Compliance: The implementation follows the Material Design specification, including proper accessibility semantics and touch targets.
- Entry Mode Flexibility: Supports
TimePickerEntryMode.dial(clock face),TimePickerEntryMode.input(text fields), and locked variants (dialOnly,inputOnly).
Basic Implementation of showTimePicker
To implement a time picker in Flutter, import the Material library and invoke the asynchronous showTimePicker function with a BuildContext and initial TimeOfDay.
import 'package:flutter/material.dart';
Future<void> _selectTime(BuildContext context) async {
final TimeOfDay? selectedTime = await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
initialEntryMode: TimePickerEntryMode.dial,
);
if (selectedTime != null) {
print('Selected: ${selectedTime.format(context)}');
}
}
The function returns a Future<TimeOfDay?>, resolving to null when the user cancels the dialog. As implemented in lines 48-71 of time_picker.dart, showTimePicker constructs the TimePickerDialog with supplied parameters and presents it through the Navigator.
Handling the TimeOfDay Result
The TimeOfDay class represents a clock time independent of date. When the user confirms their selection, extract the hour and minute components:
if (selectedTime != null) {
final int hour = selectedTime.hour;
final int minute = selectedTime.minute;
// Store in state or perform business logic
}
Customizing Time Picker Entry Modes
The time picker in Flutter supports multiple input methods controlled by the initialEntryMode parameter. The dialog includes a mode-switch button allowing users to toggle between dial and input views unless restricted.
TimePickerEntryMode.dial: Clock face with draggable hands (default).TimePickerEntryMode.input: Text fields for hour and minute entry.TimePickerEntryMode.dialOnly: Clock face without mode switching capability.TimePickerEntryMode.inputOnly: Text input without mode switching capability.
Theming with TimePickerThemeData
Global styling is achieved through TimePickerThemeData, defined in packages/flutter/lib/src/material/time_picker_theme.dart. The dialog reads theme data via TimePickerTheme.of(context), falling back to _TimePickerDefaults for Material 2 or _TimePickerDefaultsM3 for Material 3.
MaterialApp(
theme: ThemeData(
useMaterial3: true,
timePickerTheme: TimePickerThemeData(
backgroundColor: Colors.grey[900],
hourMinuteColor: Colors.blue[800],
dialHandColor: Colors.orange,
dayPeriodColor: Colors.blueGrey,
),
),
)
Localization and 24-Hour Format Support
The picker automatically adapts to locale settings through MaterialLocalizations.timeOfDayFormat. To override the device's default clock format, wrap the picker with a MediaQuery specifying alwaysUse24HourFormat.
await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
builder: (context, child) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(alwaysUse24HourFormat: true),
child: child!,
);
},
);
This configuration ensures the dialog displays 24-hour format regardless of regional settings, as the picker consults MediaQuery.alwaysUse24HourFormat when building the time display.
Summary
- Use
showTimePickerfrompackages/flutter/lib/src/material/time_picker.dartfor the most efficient time picker implementation in Flutter mobile apps. - The function returns a
Future<TimeOfDay?>that completes when the user confirms or cancels the dialog. - Customize appearance through
TimePickerThemeDataand control input methods viaTimePickerEntryModeparameters. - Force 24-hour display by overriding
MediaQuery.alwaysUse24HourFormatin the builder callback. - The built-in solution provides accessibility support, Material compliance, and optimized performance without third-party dependencies.
Frequently Asked Questions
What is the difference between showTimePicker and TimePickerDialog?
showTimePicker is a convenience function that creates and displays a TimePickerDialog using showDialog. While you can instantiate TimePickerDialog directly for custom routing scenarios, showTimePicker handles the common case of modal presentation and returns a typed Future<TimeOfDay?>.
How do I force a 24-hour clock format in Flutter's time picker?
Wrap the child widget in the builder parameter with a MediaQuery that sets alwaysUse24HourFormat: true. This overrides the system locale setting and forces the dial or input fields to display 24-hour format.
Can I customize the colors and styling of the time picker?
Yes. Define a TimePickerThemeData in your ThemeData configuration to globally style background colors, dial hands, and text styles. For specific instances, pass cancelText, confirmText, and helpText parameters directly to showTimePicker.
Is the Flutter time picker accessible for screen readers?
The Material time picker implementation includes rich semantic labels for hour/minute controls, dial gestures, and period selection (AM/PM). The dialog properly announces values and supports navigation via TalkBack (Android) and VoiceOver (iOS) without additional configuration.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →