개요
앱에서 사용자로부터 날짜를 입력받기 위해 다음과 같이 달력(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로 개발되었습니다.관심있으신 분들은 앱을 다운로드하여 사용해 주시면 정말 감사하겠습니다.