7.4 C
New York
Monday, December 11, 2023

Working with Time Picker in Flutter (Null Safety)

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.Advertisements

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,
  String? errorInvalidText,
  String? hourLabelText,
  String? minuteLabelText,
  RouteSettings? routeSettings,
  EntryModeChangeCallback? onEntryModeChanged
})

Details about the main parameters:

Parameters Type Description
context (required) BuildContext A handle to the location of the date picker in the widget tree
initialTime (required) TimeOfDay The time at the beginning
builder TransitionBuilder Wrap the dialog widget to add inherited widgets
useRootNavigator bool Determine use Root Navigator or not. Default is true.
initialEntryMode TimePickerEntryMode Determine the initial time entry selection (clock or text)
cancelText String Text on the cancel button (CANCEL is the default)
confirmText String text on the OK button (OK is the default)
helpText String The text on the top left of the picker (SELECT TIME is the default)
routeSettings RouteSettings Example: RouteSettings(name: ‘abc’, arguments: ‘xyz’)

Formatting the returned Result

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

AdvertisementsIf 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

Advertisements

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 will be displayed 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(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

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

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @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: const Text('Kindacode.com'),
      ),
      body: Center(
        child: Text(
          _selectedTime != null ? _selectedTime! : 'No time selected!',
          style: const TextStyle(fontSize: 30),
        ),
      ),
      floatingActionButton: ElevatedButton(
          onPressed: _show, child: const Text('Show Time Picker')),
    );
  }
}

Customizing Time Picker

Using 24-Hour / 12-Hour Format

The above example creates a time picker in the 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, childWidget) {
          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: childWidget!);
});

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(
        timePickerTheme: TimePickerThemeData(
          backgroundColor: Colors.amberAccent,
          shape:
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
          hourMinuteShape: const CircleBorder(),
        ),
        colorScheme: ColorScheme.fromSwatch(primarySwatch: Colors.green)
            .copyWith(secondary: Colors.greenAccent),
      ),
      home: const HomePage(),
    );

And you will see:

AdvertisementsThe full source code:

// main.dart
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(
      // Remove the debug banner
      debugShowCheckedModeBanner: false,
      title: 'Kindacode.com',
      theme: ThemeData(
        timePickerTheme: TimePickerThemeData(
          backgroundColor: Colors.amberAccent,
          shape:
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
          hourMinuteShape: const CircleBorder(),
        ),
        colorScheme: ColorScheme.fromSwatch(primarySwatch: Colors.green)
            .copyWith(secondary: Colors.greenAccent),
      ),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @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, child) {
          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: child!);
        });
    if (result != null) {
      setState(() {
        _selectedTime = result.format(context);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Kindacode.com'),
      ),
      body: Center(
        child: Text(
          _selectedTime != null ? _selectedTime! : 'No time selected!',
          style: const TextStyle(fontSize: 30),
        ),
      ),
      floatingActionButton: ElevatedButton(
          onPressed: _show, child: const 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 category page or Dart category page for the latest tutorials and examples.

Advertisements

Related Articles

Latest Articles