Working with Date and Time Picker Widgets in Flutter

Flutter provides excellent support for handling user input related to dates and times through its rich set of widgets. The Date and Time Picker Widgets in Flutter are essential tools for any application requiring users to select specific dates or times. This comprehensive guide will walk you through using these widgets effectively.

Understanding Date and Time Pickers in Flutter

Date and time pickers are pre-built UI components that allow users to select a date, a time, or both, from a calendar or a clock interface. These pickers streamline the data input process, making it more user-friendly than manual text entry.

Why Use Date and Time Pickers?

  • Enhanced User Experience: Provides an intuitive way for users to select dates and times.
  • Data Validation: Ensures the data entered is in the correct format.
  • Consistency: Standardizes date and time selection across your application.

How to Implement Date and Time Pickers in Flutter

Flutter offers two primary widgets for handling date and time input:

  • showDatePicker: Displays a calendar interface for selecting dates.
  • showTimePicker: Displays a clock interface for selecting times.

Using showDatePicker Widget

Step 1: Basic Implementation

To display a date picker, use the showDatePicker function. Here’s a simple example:


import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Date Picker Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State {
  DateTime? selectedDate;

  Future _selectDate(BuildContext context) async {
    final DateTime? picked = await showDatePicker(
      context: context,
      initialDate: DateTime.now(),
      firstDate: DateTime(2000),
      lastDate: DateTime(2025),
    );
    if (picked != null && picked != selectedDate)
      setState(() {
        selectedDate = picked;
      });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Date Picker Example'),
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Text(
              selectedDate == null
                  ? 'No date chosen!'
                  : 'Selected date: ${selectedDate!.toLocal()}'.split(' ')[0],
            ),
            SizedBox(height: 20.0),
            ElevatedButton(
              onPressed: () => _selectDate(context),
              child: Text('Select date'),
            ),
          ],
        ),
      ),
    );
  }
}

In this code:

  • showDatePicker is called with parameters such as context, initialDate, firstDate, and lastDate.
  • The initialDate sets the date that is initially displayed when the picker appears.
  • firstDate and lastDate define the range of dates that the user can select.
  • When a date is picked, the state is updated, and the selected date is displayed.
Step 2: Customizing showDatePicker

You can customize the appearance and behavior of showDatePicker using various parameters:


Future _selectDate(BuildContext context) async {
  final DateTime? picked = await showDatePicker(
    context: context,
    initialDate: DateTime.now(),
    firstDate: DateTime(2000),
    lastDate: DateTime(2025),
    helpText: 'Select booking date', // Customize the help text
    cancelText: 'Not now',         // Customize the cancel text
    confirmText: 'Book',           // Customize the confirm text
    errorFormatText: 'Enter valid date',// Error message for invalid format
    errorInvalidText: 'Date out of range',// Error message for invalid date
    builder: (BuildContext context, Widget? child) {
      return Theme(
        data: ThemeData.light().copyWith(
          primaryColor: Colors.green,  // Head color
          hintColor: Colors.greenAccent,// Accent color
          colorScheme: ColorScheme.light(primary: Colors.green),
          buttonTheme: ButtonThemeData(textTheme: ButtonTextTheme.primary),
        ),
        child: child!,
      );
    },
  );
  if (picked != null && picked != selectedDate)
    setState(() {
      selectedDate = picked;
    });
}

Here, you can see customizations for:

  • Text labels such as helpText, cancelText, and confirmText.
  • Error messages for invalid formats and out-of-range dates.
  • The theme is customized to change the primary and accent colors, providing a consistent look with your app’s design.

Using showTimePicker Widget

Step 1: Basic Implementation

To display a time picker, use the showTimePicker function. Here’s a basic example:


import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Time Picker Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State {
  TimeOfDay? selectedTime;

  Future _selectTime(BuildContext context) async {
    final TimeOfDay? picked = await showTimePicker(
      context: context,
      initialTime: TimeOfDay.now(),
    );
    if (picked != null && picked != selectedTime)
      setState(() {
        selectedTime = picked;
      });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Time Picker Example'),
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Text(
              selectedTime == null
                  ? 'No time chosen!'
                  : 'Selected time: ${selectedTime!.format(context)}',
            ),
            SizedBox(height: 20.0),
            ElevatedButton(
              onPressed: () => _selectTime(context),
              child: Text('Select time'),
            ),
          ],
        ),
      ),
    );
  }
}

In this example:

  • showTimePicker is invoked with context and initialTime as parameters.
  • The initialTime is set to the current time.
  • The format method of the TimeOfDay class is used to display the selected time in a user-friendly format.
Step 2: Customizing showTimePicker

You can customize the appearance of showTimePicker by adjusting the builder property and using themes.


Future _selectTime(BuildContext context) async {
  final TimeOfDay? picked = await showTimePicker(
    context: context,
    initialTime: TimeOfDay.now(),
    helpText: 'Select appointment time',
    cancelText: 'Cancel',
    confirmText: 'Set',
    builder: (BuildContext context, Widget? child) {
      return Theme(
        data: ThemeData.light().copyWith(
          timePickerTheme: TimePickerThemeData(
            backgroundColor: Colors.grey[50],
            hourMinuteTextColor: Colors.blueGrey[900],
            dayPeriodTextColor: Colors.blueGrey[900],
            dialTextColor: Colors.blueGrey[900],
            hourMinuteShape: const RoundedRectangleBorder(
                borderRadius: BorderRadius.all(Radius.circular(8))),
            dayPeriodShape: const RoundedRectangleBorder(
                borderRadius: BorderRadius.all(Radius.circular(8))),
            dialShape: const RoundedRectangleBorder(
                borderRadius: BorderRadius.all(Radius.circular(8))),
          ),
        ),
        child: child!,
      );
    },
  );
  if (picked != null && picked != selectedTime)
    setState(() {
      selectedTime = picked;
    });
}

In this customized example:

  • helpText, cancelText, and confirmText are customized to align with the app’s terminology.
  • The theme for the time picker is configured within the builder parameter using TimePickerThemeData, allowing for changes in background color, text color, and shape of the picker elements.

Best Practices for Using Date and Time Pickers

  • Provide Clear Labels: Use labels to clearly indicate the purpose of the date and time picker.
  • Set Appropriate Ranges: Limit the date range to avoid confusion and invalid inputs.
  • Use Consistent Formatting: Format dates and times consistently throughout your application.
  • Handle Null Values: Always check for null values returned by the pickers to avoid errors.

Conclusion

Implementing Date and Time Picker Widgets in Flutter is a straightforward way to enhance user experience and ensure data validity. By using showDatePicker and showTimePicker with appropriate customizations, you can provide a seamless and intuitive way for users to select dates and times in your Flutter applications.