Building a Date and Time Picker in Flutter: A Step-by-Step Guide

To implement a date and time picker dialog in a mobile app. The app allows users to select a date and time and displays the chosen values in a widget on the screen. The code uses the showDatePicker() and showTimePicker() functions from the Flutter framework to create the dialogs for selecting the date and time. 

The selected date and time are then formatted and displayed in the app's UI using the setState() function & example for anyone looking to implement date and time pickers in a Flutter app (Without using any 3rd party plugin).

picker_date_time.dart

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_uix/layouts/picker/utils.dart';

class PickerDateTimeRoute extends StatefulWidget {

  const PickerDateTimeRoute({super.key});

  @override
  PickerDateTimeRouteState createState() => PickerDateTimeRouteState();
}


class PickerDateTimeRouteState extends State<PickerDateTimeRoute> {

  late Future<DateTime?> selectedDate;
  String date = "-";

  late Future<TimeOfDay?> selectedTime;
  String time = "-";



  @override
  Widget build(BuildContext context) {
    return Scaffold(
     // backgroundColor: Colors.white,
      body: Column(
        children: <Widget>[

          const Spacer(flex: 10),

          Container(
            alignment: Alignment.center,
            width: double.infinity,
            height: 45,
            color: Colors.grey[300],
            child:
            Text("$date : $time"),
          ),


          Align(
            alignment: Alignment.center,
            child: ElevatedButton(
              style: ElevatedButton.styleFrom(
                  elevation: 0, backgroundColor: Theme.of(context).colorScheme.primary,
                  shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
                  padding: const EdgeInsets.symmetric(horizontal: 30)
              ),
              child: const Text("PICK DATE", style: TextStyle(color: Colors.white)),
              onPressed: (){
                showDialogPicker(context);
              },
            ),
          ),

          Align(
            alignment: Alignment.center,
            child: ElevatedButton(
              style: ElevatedButton.styleFrom(
                  elevation: 0, backgroundColor: Theme.of(context).colorScheme.primary,
                  shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
                  padding: const EdgeInsets.symmetric(horizontal: 30)
              ),
              child: const Text("PICK TIME", style: TextStyle(color: Colors.white)),
              onPressed: (){
                showDialogTimePicker(context);
              },
            ),
          )

        ],
      ),
    );
  }



  void showDialogPicker(BuildContext context){
    selectedDate = showDatePicker(
      context: context,
      helpText: 'Your Date of Birth',
      initialDate: DateTime.now(),
      firstDate: DateTime(2000),
      lastDate: DateTime(2050),
      builder: (BuildContext context, Widget? child) {
        return Theme(
          data: ThemeData.light().copyWith(
            colorScheme:  ColorScheme.light(
             // primary: MyColors.primary,
              primary: Theme.of(context).colorScheme.primary,
              onPrimary: Colors.white,
              surface: Colors.white,
              onSurface: Colors.black,
            ),
            //.dialogBackgroundColor:Colors.blue[900],
          ),
          child: child!,
        );
      },
    );
    selectedDate.then((value) {
      setState(() {
        if(value == null) return;
        date = Utils.getFormattedDateSimple(value.millisecondsSinceEpoch);
      });
    }, onError: (error) {
      if (kDebugMode) {
        print(error);
      }
    });
  }

  void showDialogTimePicker(BuildContext context){
    selectedTime = showTimePicker(
      context: context,
      initialTime: TimeOfDay.now(),
      builder: (BuildContext context, Widget? child) {
        return Theme(
          data: ThemeData.light().copyWith(
            colorScheme: ColorScheme.light(
              // primary: MyColors.primary,
              primary: Theme.of(context).colorScheme.primary,
              onPrimary: Colors.white,
              surface: Colors.white,
              onSurface: Colors.black,
            ),
            //.dialogBackgroundColor:Colors.blue[900],
          ),
          child: child!,
        );
      },
    );
    selectedTime.then((value) {
      setState(() {
        if(value == null) return;
        time = "${value.hour} : ${value.minute}";
      });
    }, onError: (error) {
      if (kDebugMode) {
        print(error);
      }
    });
  }

}

utils.dart

This is a utility class in a Flutter app that provides a static method getFormattedDateSimple which takes an integer representing time in milliseconds since the epoch and returns a formatted string in the format "MMMM dd, yyyy".


The DateFormat class from the intl package is used to format the date and the method returns the formatted date string. This method can be used in a Flutter app for formatting dates according to the desired format.

import 'package:intl/intl.dart';

class Utils {

  static String getFormattedDateSimple(int time) {
    DateFormat newFormat = DateFormat("MMMM dd, yyyy");
    return newFormat.format(DateTime.fromMillisecondsSinceEpoch(time));
  }

}

..

showDialogPicker() explanation:

void showDialogPicker(BuildContext context) {
  // Show a date picker dialog and save the selected date in a Future
  selectedDate = showDatePicker(
    context: context,
    helpText: 'Your Date of Birth',
    initialDate: DateTime.now(),
    firstDate: DateTime(2000),
    lastDate: DateTime(2050),
    builder: (BuildContext context, Widget? child) {
      // Customize the appearance of the date picker dialog
      return Theme(
        data: ThemeData.light().copyWith(
          colorScheme:  ColorScheme.light(
            primary: Theme.of(context).colorScheme.primary,
            onPrimary: Colors.white,
            surface: Colors.white,
            onSurface: Colors.black,
          ),
        ),
        child: child!,
      );
    },
  );
  // When the user selects a date, update the state with the new date value
  selectedDate.then((value) {
    setState(() {
      if (value == null) return;
      date = Utils.getFormattedDateSimple(value.millisecondsSinceEpoch);
    });
  }, onError: (error) {
    // Handle any errors that occur while selecting a date
    if (kDebugMode) {
      print(error);
    }
  });
}

showDialogPicker which shows a dialog for the user to pick a date.

selectedDate is assigned the result of the showDatePicker method, which displays a date picker dialog and returns a future containing the selected date.


The date picker dialog is displayed using the showDatePicker method, which takes several parameters:

context: the build context in which to display the dialog.

helpText: a text string to display above the date picker.

initialDate: the initial date to display in the picker. In this case, it's set to the current date.

firstDate: the earliest date that can be selected.

lastDate: the latest date that can be selected.

builder: a callback function that builds the dialog widget. In this case, it returns a Theme widget with a light color scheme.

Once a date is selected, the then method is called on the selectedDate future. This method takes two callbacks:

onValue: a callback function that is called if the future resolves successfully. In this case, it updates the date variable with the selected date, formatted using the getFormattedDateSimple method from the Utils class.

onError: a callback function that is called if the future resolves with an error. In this case, it prints the error to the console if the app is in debug mode.

Overall, this function is used to display a date picker dialog and handle the selected date.

..

showDialogTimePicker() explanation:

void showDialogTimePicker(BuildContext context){
  // Show the time picker dialog and return the selected time as a Future.
  selectedTime = showTimePicker(
    context: context,
    initialTime: TimeOfDay.now(),
    builder: (BuildContext context, Widget? child) {
      // Customize the look and feel of the dialog using a custom theme.
      return Theme(
        data: ThemeData.light().copyWith(
          colorScheme: ColorScheme.light(
            // primary: MyColors.primary,
            primary: Theme.of(context).colorScheme.primary,
            onPrimary: Colors.white,
            surface: Colors.white,
            onSurface: Colors.black,
          ),
          //.dialogBackgroundColor:Colors.blue[900],
        ),
        child: child!,
      );
    },
  );
  // When the user selects a time, update the state of the widget with the new time value.
  selectedTime.then((value) {
    setState(() {
      if(value == null) return;
      time = "${value.hour} : ${value.minute}";
    });
  }, onError: (error) {
    // Handle any errors that occur when selecting a time (e.g. user cancels).
    if (kDebugMode) {
      print(error);
    }
  });
}

The showDialogTimePicker function is called when the user taps on a button or other UI element to show the time picker dialog.

The showTimePicker function is called to display the time picker dialog and return a Future that will eventually contain the selected time.

The initialTime parameter is used to set the initial value of the time picker to the current time of day.

The builder parameter is used to customize the look and feel of the dialog using a custom theme. In this case, the Theme widget is used to apply a light color scheme with a primary color that matches the primary color of the app's current theme.

When the user selects a time, the selectedTime Future is completed with the selected value.

The then method is used to update the state of the widget with the new time value. If the selected value is null (e.g. if the user cancels), no update is performed.

The onError callback is used to handle any errors that occur when selecting a time (e.g. if an exception is thrown). In this case, any errors are printed to the console if the app is running in debug mode.

..

..


Try this Material & Cupertino picker




Comments