A Deep Dive Into DatePicker In Flutter

Exploring how to make use of DatePicker using showDatePicker function.

Pinkesh Darji
Flutter Community

--

There are a lot of use cases where users need to enter the date. A very common example is to enter the date of birth, Book a ticket, Make a restaurant reservation, Schedule a meeting, etc.

So how do we allow the user to enter the date which provides the best user experience?

Instead of creating our own UI to let the user enter the date, The best solution is to use an already available view or widget like DatePicker in the respective Platform.

So how do we do that in Flutter?

🎤 Presenting the showDatePicker function

Shows a dialog containing a Material Design date picker.

The basic code looks like this…

showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2000),
lastDate: DateTime(2025),
)

Do you want to stay updated in Flutter world? Please click on subscribe button to get an email when the new tutorial is published or visit the https://flutterbeads.com/

Let’s try to build something like this.

Step : Prepare a variable

/// Which holds the selected date
/// Defaults to today's date.
DateTime selectedDate = DateTime.now();

Step : Setup UI

Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
"${selectedDate.toLocal()}".split(' ')[0],
style: TextStyle(fontSize: 55, fontWeight: FontWeight.bold),
),
SizedBox(
height: 20.0,
),
RaisedButton(
onPressed: () => _selectDate(context), // Refer step 3
child: Text(
'Select date',
style:
TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
),
color: Colors.greenAccent,
),
],
)

A minimal UI consists of Text to show date and RaisedButton to open DatePicker dialog.

Step : Write a Method to call showDatePicker function

_selectDate(BuildContext context) async {
final DateTime picked = await showDatePicker(
context: context,
initialDate: selectedDate, // Refer step 1
firstDate: DateTime(2000),
lastDate: DateTime(2025),

);
if (picked != null && picked != selectedDate)
setState(() {
selectedDate = picked;
});

}

This method actually calls showDatePicker function and waits for the date selected by the user. If a user does not select anything then the date return will be null otherwise the selected date.

Note:

The initialDate property is used to display a default date when DatePicker dialog is opened.

SetState will be called to update the selected date in UI and you are done.

⚫ How to show/display only a specific date range?

Just by setting the firstDate and the lastDate properties like this…

showDatePicker(
context: context,
initialDate: selectedDate,
firstDate: DateTime(2000), // Required
lastDate: DateTime(2025), // Required

)

This will allow the user to enter the date between 1st January 2000 to 1st January 2025.

⚫ How to show the Text input box instead of the calendar?

Sometimes it becomes difficult for old age people to interact with the calendar for changing the dates especially when they use it for the first time.

In such a situation it is better to just provide an input box to enter the date, and this can be done very easily just by setting initialEntryMode property.

showDatePicker(
context: context,
initialDate: selectedDate,
firstDate: DateTime(2000),
lastDate: DateTime(2025),
initialEntryMode: DatePickerEntryMode.input,
)

⚫ How to show the year’s list first?

Sometimes you are very sure that the user will enter the date from the past years like date of birth, In such a case you can directly show the year’s list instead of showing a list of days then making users open the year list.

Setting initialDatePickerMode to DatePickerMode.year will do the work. This will save one-click for users, which is good.

showDatePicker(
context: context,
initialDate: selectedDate,
firstDate: DateTime(2000),
lastDate: DateTime(2025),
initialDatePickerMode: DatePickerMode.year,
)

⚫ How to allow the user to enter a date from a specific range?

What if we want to enable only a few dates within a month. Users can see the dates in the whole month but select only a few which we decide to enable.

selectableDayPredicate property comes to the rescue. We can simply pass here the function which decides which dates to enable.

/// This decides which day will be enabled
/// This will be called every time while displaying day in calender.

bool _decideWhichDayToEnable(DateTime day) {
if ((day.isAfter(DateTime.now().subtract(Duration(days: 1))) &&
day.isBefore(DateTime.now().add(Duration(days: 10))))) {
return true;
}
return false;
}
showDatePicker(
context: context,
initialDate: selectedDate,
firstDate: DateTime(2000),
lastDate: DateTime(2025),
selectableDayPredicate: _decideWhichDayToEnable,
)

This code will allow the user to enter a date within 10 days starting from today.

⚫ How to change the Text?

These highlighted texts can be changed very easily by setting below properties.

showDatePicker(
context: context,
initialDate: selectedDate,
firstDate: DateTime(2000),
lastDate: DateTime(2025),
helpText: 'Select booking date', // Can be used as title
cancelText: 'Not now',
confirmText: 'Book',

)

⚫ How to change the error messages?

When the user tries to enter the date via text input box, there is a high chance of making a mistake like giving an invalid date.

By default, this widget provides some predefined error text but you can always change it if you want in a case like assisting users what to do next instead of just showing the message.

showDatePicker(
context: context,
initialDate: selectedDate,
firstDate: DateTime(2000),
lastDate: DateTime(2025),
errorFormatText: 'Enter valid date',
errorInvalidText: 'Enter date in valid range',

)

⚫ How to change the label and hint text?

showDatePicker(
context: context,
initialDate: selectedDate,
firstDate: DateTime(2000),
lastDate: DateTime(2025),
fieldLabelText: 'Booking date',
fieldHintText: 'Month/Date/Year',

)

⚫ How to change the theme?

Simply by making the use of the builder parameter you can wrap the dialog widget inside theme like this.

showDatePicker(
context: context,
initialDate: selectedDate,
firstDate: DateTime(2000),
lastDate: DateTime(2025),
builder: (context, child) {
return Theme(
data: ThemeData.light(), // This will change to light theme.
child: child,
);
}
,
)

⚫ How to open native-like DatePicker in the Target platform?

If you have noticed carefully that we have kept on opening Material design date picker in the iOS device! so how do we go for Cupertino Datepicker in iOS?

It's pretty simple than you imagine!

We just need to check which target platform it is and show the respective DatePicker and yes Flutter has also covered the CupertinoDatePicker.

_selectDate(BuildContext context) async {
final ThemeData theme = Theme.of(context);
assert(theme.platform != null);
switch (theme.platform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
return buildMaterialDatePicker(context);
case TargetPlatform.iOS:
case TargetPlatform.macOS:
return buildCupertinoDatePicker(context);
}
}
/// This builds material date picker in Android
buildMaterialDatePicker(BuildContext context) async {
final DateTime picked = await showDatePicker(
context: context,
initialDate: selectedDate,
firstDate: DateTime(2000),
lastDate: DateTime(2025),
builder: (context, child) {
return Theme(
data: ThemeData.light(),
child: child,
);
},
);
if (picked != null && picked != selectedDate)
setState(() {
selectedDate = picked;
});
}
/// This builds cupertion date picker in iOS
buildCupertinoDatePicker(BuildContext context) {
showModalBottomSheet(
context: context,
builder: (BuildContext builder) {
return Container(
height: MediaQuery.of(context).copyWith().size.height / 3,
color: Colors.white,
child: CupertinoDatePicker(
mode: CupertinoDatePickerMode.date,
onDateTimeChanged: (picked) {
if (picked != null && picked != selectedDate)
setState(() {
selectedDate = picked;
});
},
initialDateTime: selectedDate,
minimumYear: 2000,
maximumYear: 2025,
),
);
});
}

Play with the full code here

That’s it. I hope you have learned something new from this article.

Little about me

Hi, Myself Pinkesh Darji, I love to solve problems using technology that improves user’s life on a major scale. Over the last several years, I have been developing and leading various mobile apps in different areas. More than just programming, I love to write technical articles.

I write about Flutter at https://flutterbeads.com/. A place to learn Flutter from high-quality tutorials.

--

--