【Flutter/Dart】日付選択UIの実装方法!showDatePicker/CupertinoDatePickerの使い方

この記事からわかること
- Flutter/Dartで日付選択ピッカーを実装する方法
- showDatePicker/CupertinoDatePickerの使い方
index
[open]
\ アプリをリリースしました /
環境
- Android Studio:Koala
- Xcode:16.0
- Flutter:3.29.2
- Dart:3.7.2
- Mac M1:Sonoma 14.6.1
日付選択ピッカーの実装方法
Flutterで日付を選択できるピッカーUIを実装する方法は2つ存在します。両者の実装方法と違いなどをまとめていきたいと思います。
- showDatePicker・・・カレンダーUI
- CupertinoDatePicker・・・iOSライクなホイールピッカー
showDatePicker
1つ目の方法はshowDatePicker
メソッドを使用する方法です。showDatePicker
メソッドを実行するとカレンダーUIのポップアップが表示され、日付を選択することが可能になります。

実装方法は簡単でinitialDate
に初期選択状態となる日付を渡して呼び出すだけです。await
を使用して選択した日付が取得できるように実装します。
final TextEditingController _dateController = TextEditingController();
void _selectDate(BuildContext context) async {
DateTime? picked = await showDatePicker(
context: context,
// 初期日付
initialDate: DateTime.now(),
// 最小選択範囲
firstDate: DateTime(2000),
// 最大選択範囲
lastDate: DateTime(2100),
);
if (picked != null) {
_dateController.text = "${picked.year}/${picked.month}/${picked.day}";
}
}
※ デフォルトではロケールの設定がされていないため画像のように日本語化されていません。ローカライズの方法は後述しています。
CupertinoDatePicker
2つ目はCupertinoDatePicker
Widgetを使用したiOSライクなホイールピッカーを実装する方法です。こちらはWidgetなのでshowModalBottomSheet
などを使用してモーダル表示させるように使用すると使いやすいです。(※ Cupertino(クパチーノ)はiOSスタイルの UIを作るためのWidgetを提供するパッケージです)

こちらもinitialDateTime
に初期選択状態となる日付を渡します。
import 'package:flutter/cupertino.dart';
void _showCupertinoDatePicker(BuildContext context) {
showModalBottomSheet(
context: context,
builder: (BuildContext builder) {
return Container(
height: 250,
child: CupertinoDatePicker(
mode: CupertinoDatePickerMode.date,
initialDateTime: DateTime.now(),
onDateTimeChanged: (DateTime newDate) {
print("選択した日付: $newDate");
},
),
);
},
);
}
※ こちらもデフォルトではロケールの設定がされていないため画像のように日本語化されていません。
ローカライズ(日本語化)
日付ピッカーをローカライズ(今回は日本語化)するためにはflutter_localizations
パッケージを使用します。(flutter_localization(sなし)
というパッケージが「pub.dev」にありますが別物なので注意してください)
まずは以下のコマンドを実行してインストールしておきます。この際にintl
がすでに導入済みの場合、バージョンによっては競合エラー(後述)が発生する場合があります。
$ flutter pub add flutter_localizations --sdk=flutter
導入できたらMaterialApp
の引数localizationsDelegates
とsupportedLocales
にそれぞれ値を追加します。supportedLocales
にはローカライズ対象のLocale
をリスト形式で指定すればOKです。今回は日本語化なのでLocale('ja', 'JP')
を指定するとピッカーが日本語対応されます。
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My Test App',
localizationsDelegates: [
// マテリアル Widget(Android)
GlobalMaterialLocalizations.delegate,
// 共通 Widget
GlobalWidgetsLocalizations.delegate,
// クパチーノ Widget(iOS)
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
// 日本語
Locale('ja', 'JP'),
],
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: CustomColors.thema),
),
home: HomeRootView(),
);
}
}
intlバージョンの競合エラー
intl
がすでに導入済みの場合、バージョンによっては競合エラーが発生する場合があります。以下ではintl 0.20.2
をすでに導入済みでflutter_localizations
パッケージをインストールしようとするとintl 0.19.0
がサポート対象だよと怒られるので、intl
のバージョンを下げてあげれば解消します。
ntl is pinned to version 0.19.0 by flutter_localizations from the flutter SDK.
See https://dart.dev/go/sdk-version-pinning for details.
Because every version of flutter_localizations from sdk depends on intl 0.19.0
and salary depends on intl ^0.20.2, flutter_localizations from sdk is
forbidden.
So, because salary depends on flutter_localizations from sdk, version solving
failed.
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。