概要
アプリでユーザから日付を入力してもらうため、次のようにカレンダー(DatePicker)を表示するUIをよく見ます。
今回のブログポストではshowDatePicker
を使ってFlutter
でDatePicker
を表示する方法について説明します。
- showDatePicker: https://api.flutter.dev/flutter/material/showDatePicker.html
ここで紹介するソースコードはGitHub
で確認できます。
プロジェクト準備
showDatePicker
の使い方を確認するため、次のようにボタンを表示する簡単なアプリを作ってみます。
次のコマンドを実行して新しいFlutterプロジェクトを生成します。
flutter create show_date_picker
新しいFlutterプロジェクトが生成されたら、main.dart
ファイルを開いて下記のように修正します。
class _MyHomePageState extends State<MyHomePage> {
DateTime date = DateTime.now();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Date Picker Example'),
),
body: Center(
child: ElevatedButton(
onPressed: () {},
child: Text(
"${date.year.toString()}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}",
),
),
),
);
}
}
DatePicker
を使ってボタンに表示される日付を変更する予定なので、Stateful
ウィジェットで生成しました。このようにmain.dart
ファイルを修正して保存すると、下記のようにボタンがうまく表示されることが確認できます。
今はボタンイベントに何もコードを追加してないので、ボタンを押しても何の動作もしないことが確認できます。
showDatePicker
次は、showDatePicker
を使ってDatePickerを表示する方法についてみてみます。ボタンを押した時、showDatePicker
を表示するためElevatedButton
ウィジェットのonPressed
関数を下記のように修正します。
...
ElevatedButton(
onPressed: () async {
final selectedDate = await showDatePicker(
context: context,
initialDate: date,
firstDate: DateTime(2000),
lastDate: DateTime.now(),
);
if (selectedDate != null) {
setState(() {
date = selectedDate;
});
}
},
...,
),
...
showDatePicker
関数はFuture<DateTime?>
タイプを返すので、async-await
を使う必要があります。また、ユーザが日付を選択しない場合、null
が帰ってくるので、ユーザが選択した日付を保存するためif
文を使いました。最後に、ユーザが選択した日付をsetState
を使ってState
を変更して、画面をアップデートするようにしました。
このようにコードを修正して保存すると、次のようにボタンがまだうまく表示されることが確認できます。
そしたら、ボタンを押してみます。ボタンを押したら以前と違って次のようにカレンダーが表示されることが確認できます。
次はカレンダーで好きな日付を押すと、次のようにボタンの日付がうまく変更されることが確認できます。
initialEntryMode
現在表示されたDatePicker
の右上にある修正アイコンを押すと次のように日付を直接入力する画面が確認されます。
この機能を使えないようにするためには、次のようにshowDatePicker
関数のinitialEntryMode
オプションにDatePickerEntryMode.calendarOnly
を設定する必要があります。
...
ElevatedButton(
onPressed: () async {
final selectedDate = await showDatePicker(
context: context,
initialDate: date,
firstDate: DateTime(2000),
lastDate: DateTime.now(),
initialEntryMode: DatePickerEntryMode.calendarOnly,
);
if (selectedDate != null) {
setState(() {
date = selectedDate;
});
}
},
...,
),
...
そしたら次のように右上に表示された修正アイコンが消えることが確認できます。
多言語
カレンダーに表示される言語を英語ではなく他の言語で表示するためにはflutter_localizations
パッケージをインストールする必要があります。次のコマンドを使ってflutter_localizations
パッケージをインストールします。
flutter pub add flutter_localizations --sdk=flutter
または、pubspec.yaml
ファイルを次のように修正してflutter_localizations
パッケージをインストールする。
...
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
...
その後、次のようにMaterialApp
にlocalizationsDelegates
オプションを追加します。
import 'package:flutter_localizations/flutter_localizations.dart';
...
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
...,
);
}
}
...
その後、showDatePicker
関数のlocale
オプションに表示したい言語を設定します。ここでは日本語(Japanese)を設定しました。
...
final selectedDate = await showDatePicker(
context: context,
initialDate: date,
firstDate: DateTime(2000),
lastDate: DateTime.now(),
initialEntryMode: DatePickerEntryMode.calendarOnly,
locale: const Locale('ja', 'JP'),
);
...
このようにコードを修正して保存すると、次のようにカレンダーに表示される言語が英語ではなく日本語がうまく表示されることが確認できます。
テストコード
次のようにテストコードを作成して、showDatePicker
がうまく動作するか確認することができます。
...
testWidgets('Change date by DatePicker', (WidgetTester tester) async {
DateTime date = DateTime.now();
await tester.pumpWidget(const MyApp());
final year = date.year.toString();
final month = date.month.toString().padLeft(2, '0');
final day = date.day.toString().padLeft(2, '0');
expect(find.text('$year-$month-$day'), findsOneWidget);
// Press cancel test
await tester.tap(find.text('$year-$month-$day'));
await tester.pump();
await tester.tap(find.text('キャンセル')); // Cancel
await tester.pump();
expect(find.text('$year-$month-$day'), findsOneWidget);
expect(find.text('キャンセル'), findsNothing);
// Change date
await tester.tap(find.text('$year-$month-$day'));
await tester.pump();
await tester.tap(find.text('15'));
await tester.tap(find.text('OK'));
await tester.pump();
expect(find.text("$year-$month-15"), findsOneWidget);
await tester.tap(find.text('$year-$month-15'));
await tester.pump();
await tester.tap(find.text('1'));
await tester.tap(find.text('OK'));
await tester.pump();
expect(find.text("$year-$month-01"), findsOneWidget);
});
...
このテストコードではボタンを押してDatePicker
を表示した後、日本語で表示されたキャンセル(キャンセル
)ボタンを押して日付の変更をしなくてDatePicker
を閉じるテストと実際日付を押して日付を変更するテストを作成してみました。
完了
これでshowDatePicker
を使ってFlutter
でカレンダーを表示して日付を変更する機能を実装する方法について調べてみました。日付を変更する必要がある場合、日付を直接入力させるより、DatePicker
を表示してユーザがもっと楽に日付を変更することができるようにしてみてください。
私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!
アプリ広報
Deku
が開発したアプリを使ってみてください。Deku
が開発したアプリはFlutterで開発されています。興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。