flutter
date picker
flutter app development
UI components
mobile app development

What is the correct way to add date picker in flutter app?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In Flutter, the usual way to let a user choose a date is showDatePicker. The important part is not just opening the dialog. It is deciding where the selected date lives, how it is displayed in the UI, and how validation should work if the date is required for a form.

Basic showDatePicker Usage

A minimal example looks like this:

dart
1import 'package:flutter/material.dart';
2
3class DatePickerExample extends StatefulWidget {
4  const DatePickerExample({super.key});
5
6  
7  State<DatePickerExample> createState() => _DatePickerExampleState();
8}
9
10class _DatePickerExampleState extends State<DatePickerExample> {
11  DateTime? selectedDate;
12
13  Future<void> pickDate() async {
14    final picked = await showDatePicker(
15      context: context,
16      initialDate: selectedDate ?? DateTime.now(),
17      firstDate: DateTime(2000),
18      lastDate: DateTime(2100),
19    );
20
21    if (picked != null) {
22      setState(() {
23        selectedDate = picked;
24      });
25    }
26  }
27
28  
29  Widget build(BuildContext context) {
30    return ElevatedButton(
31      onPressed: pickDate,
32      child: Text(selectedDate == null
33          ? 'Pick a date'
34          : '${selectedDate!.year}-${selectedDate!.month}-${selectedDate!.day}'),
35    );
36  }
37}

This is the standard Flutter pattern: open the picker asynchronously, wait for the result, and update widget state only if the user actually selected a date.

Common Form Pattern: Read-Only Text Field

In real apps, the date picker is often attached to a form field rather than a plain button.

dart
1TextFormField(
2  readOnly: true,
3  controller: _controller,
4  decoration: const InputDecoration(
5    labelText: 'Date of birth',
6    suffixIcon: Icon(Icons.calendar_today),
7  ),
8  onTap: () async {
9    final picked = await showDatePicker(
10      context: context,
11      initialDate: DateTime.now(),
12      firstDate: DateTime(1900),
13      lastDate: DateTime.now(),
14    );
15
16    if (picked != null) {
17      _controller.text = '${picked.year}-${picked.month}-${picked.day}';
18    }
19  },
20)

This keeps the form layout consistent while preventing manual free-form typing for a value that should come from a calendar chooser.

Why showDatePicker Is Usually the Right Tool

Flutter already gives you a Material-style date picker dialog. That means the "correct way" is rarely to build a custom calendar widget from scratch unless your UX has unusual domain rules.

The built-in API handles:

  • date dialog presentation
  • localization hooks
  • date-range constraints
  • asynchronous result flow

That makes it a better default than rolling your own calendar behavior too early.

Validation and Range Rules

A good date-picker implementation sets real boundaries. For example, a birth date should not allow future dates, and a booking form may need a minimum date of today or later.

The firstDate, lastDate, and initialDate parameters are not optional design details. They are part of the form's business rules.

Store DateTime, Not Just Strings

Even if you display the selected date as text, keep the real value as a DateTime in state whenever possible. Formatting can change later, but the underlying date object remains reliable for validation, submission, and API conversion.

That separation keeps the UI representation from becoming the application's source of truth.

Keep UX and Data Rules Together

A date picker feels like a UI concern, but it is really a small piece of domain validation too. The allowed range, default value, and display format should reflect the business rule clearly so the widget does not drift away from what the form actually means.

Common Pitfalls

  • Building a custom calendar UI when showDatePicker already solves the normal requirement.
  • Forgetting to handle the case where the user cancels and the result is null.
  • Storing only a formatted string instead of the actual DateTime value.
  • Choosing weak firstDate and lastDate bounds that do not match the business rule.
  • Allowing free text entry when the field should be constrained to actual calendar selections.

Summary

  • In Flutter, showDatePicker is the normal way to add a date picker.
  • Handle the result asynchronously and check for null on cancel.
  • Use realistic date bounds to match the domain rule.
  • Keep the real date as DateTime even if the UI shows formatted text.
  • A read-only form field plus picker is often the cleanest production pattern.

Course illustration
Course illustration

All Rights Reserved.