Working with Time Picker in Flutter (2021)

Last updated on March 23, 2021 A Goodman Loading... Post a comment

This is a deep dive into time pickers in Flutter. We will explore the showTimePicker function, its parameters, and how to handle the returned result. Next, we will study an example of how to implement a time picker with a default appearance, then we will customize it by using the builder argument and the TimePickerThemeData class.

Overview

showTimePicker function

You can implement a time picker by using the showTimePicker function. This function comes with the material library so we don’t need to install any third-party plugins.

The syntax of the showTimePicker() function:

Future<TimeOfDay?> showTimePicker ({
  required BuildContext context,
  required TimeOfDay initialTime,
  TransitionBuilder? builder,
  bool useRootNavigator: true,
  TimePickerEntryMode initialEntryMode: TimePickerEntryMode.dial,
  String? cancelText,
  String? confirmText,
  String? helpText,
  RouteSettings? routeSettings
})

Details about the parameters:

ParametersTypeDescription
context (required)BuildContextA handle to the location of the date picker in the widget tree
initialTime (required)TimeOfDayThe time at the beginning
builderTransitionBuilderWrap the dialog widget to add inherited widgets
useRootNavigatorboolDetermine use Root Navigator or not. Default is true.
initialEntryModeTimePickerEntryModeDetermine the initial time entry selection (clock or text)
cancelTextStringText on the cancel button (CANCEL is the default)
confirmTextStringtext on the OK button (OK is the default)
helpTextStringThe text on the top left of the picker (SELECT TIME is the default)
routeSettingsRouteSettingsExample: RouteSettings(name: ‘abc’, arguments: ‘xyz’)

Formatting the returned Result

The function returns Future<TimeOfDay> or null (if nothing selected).

If you want to save the result as a string (for saving to a database, file, or cloud) then do as below:

final TimeofDay result = await showTimePicker(/*...*/);
final String myTime = result.format(context);

Note that using result.toString() will not give you what you want.

If you want AM/PM (day period), Hours, and Minutes, you can do like this:

final TimeofDay result = await showTimePicker(/*...*/);
if(result != null){
  print(result.period); // DayPeriod.pm or DayPeriod.am
  print(result.hour);
  print(result.minute);
}

The Example

This example app is intended to be as simple and short as possible. It contains a floating button and a Text widget in the center area. When the button is pressed, a time picker will show up and let you pick a time. The picked time willed be display on the screen.

Preview

The code

Here is the complete code for the app shown in the video above:

// main.dart
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // Remove the debug banner
      debugShowCheckedModeBanner: false,
      title: 'Kindacode.com',
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  String _selectedTime;

  // We don't need to pass a context to the _show() function
  // You can safety use context as below
  Future<void> _show() async {
    final TimeOfDay result = await showTimePicker(
        context: context, initialTime: TimeOfDay.now() );
    if (result != null) {
      setState(() {
        _selectedTime = result.format(context);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Kindacode.com'),
      ),
      body: Center(
        child: Text(
          _selectedTime != null ? _selectedTime : 'No time selected!',
          style: TextStyle(fontSize: 30),
        ),
      ),
      floatingActionButton:
          ElevatedButton(onPressed: _show, child: Text('Show Time Picker')),
    );
  }
}

Customizing Time Picker

Using 24-Hour / 12-Hour Format

The above example creates a time picker in 12-hour format. You can set it to 24-hour format by using the builder argument of the showTImePicker function like this:

showTimePicker(
        context: context,
        initialTime: TimeOfDay.now(),
        builder: (context, _) {
          return MediaQuery(
              data: MediaQuery.of(context).copyWith(
                  // Using 24-Hour format
                  alwaysUse24HourFormat: true),
                  // If you want 12-Hour format, just change alwaysUse24HourFormat to false or remove all the builder argument
              child: _);
});

Screenshot:

TimePickerThemeData

In this section, we will customize the look and feel of a time picker (colors, typography, shapes, input box styles, etc.) with the help of TimePickerThemeData.

For example, to make our time picker more gorgeous, modify the code in the MaterialApp block like this:

 return MaterialApp(
      // Remove the debug banner
      debugShowCheckedModeBanner: false,
      title: 'Kindacode.com',
      theme: ThemeData(
        primarySwatch: Colors.green,
        accentColor: Colors.greenAccent,
        timePickerTheme: TimePickerThemeData(
          backgroundColor: Colors.amberAccent,
          shape:
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
          hourMinuteShape: CircleBorder(),
        ),
      ),
      home: HomePage(),
);

And you will see:

The full source code:

// main.dart
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // Remove the debug banner
      debugShowCheckedModeBanner: false,
      title: 'Kindacode.com',
      theme: ThemeData(
        primarySwatch: Colors.green,
        accentColor: Colors.greenAccent,
        timePickerTheme: TimePickerThemeData(
          backgroundColor: Colors.amberAccent,
          shape:
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
          hourMinuteShape: CircleBorder(),
        ),
      ),
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  String _selectedTime;
  Future<void> _show() async {
    final TimeOfDay result = await showTimePicker(
        context: context,
        initialTime: TimeOfDay.now(),
        builder: (context, _) {
          return MediaQuery(
              data: MediaQuery.of(context).copyWith(
                  // Using 12-Hour format
                  alwaysUse24HourFormat: false),
              // If you want 24-Hour format, just change alwaysUse24HourFormat to true
              child: _);
        });
    if (result != null) {
      setState(() {
        _selectedTime = result.format(context);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Kindacode.com'),
      ),
      body: Center(
        child: Text(
          _selectedTime != null ? _selectedTime : 'No time selected!',
          style: TextStyle(fontSize: 30),
        ),
      ),
      floatingActionButton:
          ElevatedButton(onPressed: _show, child: Text('Show Time Picker')),
    );
  }
}

Conclusion

This article has covered the most important aspects of using martial time picker, a component you’ll need a lot when building apps with Flutter. Knowing and mastering them will make your workflow much more enjoyable. If you would like to explore more beautiful and interesting stuff in Flutter, take a look at the following articles:

You can also check out our Flutter topic page or Dart topic page for the latest tutorials and examples.

Related Articles

guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x