728x90
1. 기본 준비
✅ 필요한 패키지
패키지 | 설명 |
table_calendar | Flutter에서 다양한 달력 UI와 기능을 제공 |
intl | 날짜 및 시간 포맷 (예: yyyy-MM-dd → 2024년 05월 15일 등) |
✅ 설치 명령어 (터미널에 입력)
flutter pub add table_calendar
flutter pub add intl
pubspec.yaml
dependencies:
table_calendar: ^3.0.9 # 달력
intl: ^0.18.1 # DateFormat 사용을 위해 추가
- 달력 만들기 단계:
-
- 달력의 기본 틀(컨테이너, 격자 등) 설정
- 날짜 표시를 위한 속성 지정
- 사용자 인터랙션 위해 속성이나 명령어 추가
- 주의할 점:
- 날짜와 월/년 변경은 별도 속성 또는 명령어 사용
- 보기 쉽게 만들기 위해 스타일도 고려
-
2. 핵심 속성 정리 (table_calendar 기준)
구분 | 속성명 | 설명 |
날짜 범위 | firstDay / lastDay | 선택 가능한 최소/최대 날짜 설정 |
현재 포커스 날짜 | focusedDay | 현재 달력을 표시할 기준 날짜 |
언어 설정 | locale | 달력의 언어 설정 (ko-KR 등) |
날짜 선택 | onDaySelected | 날짜를 선택했을 때 실행되는 콜백 |
선택 조건 | selectedDayPredicate | 선택된 날짜 여부를 판단 |
스타일 설정 | headerStyle / calendarStyle | 달력 헤더, 셀 스타일 지정 |
이벤트 표시 | eventLoader | 날짜별 이벤트 점 등을 표시 |
커스터마이징 | calendarBuilders | 달력의 특정 부분을 위젯으로 재구성 가능 |
+
구분 | 이름 또는 설명 | 예시 또는 상세 설명 |
속성 (Attributes) | ||
year | 연도를 지정 | year=2025 |
month | 월을 지정 | month=5 |
day | 특정 날짜 지정 | day=15 |
startDay | 주의 시작 요일 (일, 월, 화, 등) | startDay=Monday |
showWeekNum | 주 번호 표시 여부 | showWeekNum=true |
viewMode | 달력 시작 모드 (월별, 연별 등) | viewMode=month |
highlightToday | 오늘 날짜 강조 | highlightToday=true |
명령어 / 함수 | ||
goToMonth() | 특정 월로 이동하는 함수 | goToMonth(6) (6월로 이동) |
goToYear() | 특정 연도로 이동하는 함수 | goToYear(2026) |
nextMonth() | 다음 달로 이동 | nextMonth() |
prevMonth() | 이전 달로 이동 | prevMonth() |
refresh() | 달력을 새로고침 또는 갱신 | refresh() |
위젯/컴포넌트 | ||
Calendar | 달력 전체를 감싸는 위젯 | <Calendar /> |
Header | 년월, 조작 버튼(이전/다음) 포함 | <Header /> |
DayGrid | 날짜를 격자 형태로 보여주는 부분 | <DayGrid /> |
WeekNumber | 주 번호를 보여주는 기능 | <WeekNumber /> |
DateCell | 개별 날짜 표시 셀 | <DateCell /> |
날짜 관련
날짜 지정
시작날짜를
firstDay: DateTime(2025, 1, 1),
firstDay: DateTime.now().subtract( const Duration(days: 365 * 10));
lastDay: DateTime.now().add( const Duration(days: 365 * 10));
DateTime.now() 지금 일자
.subtract 빼기
.add 더하기
구분 | 항목 | 설명 / 기능 | 예시 / 참고 |
기본 날짜/시간 자료구조 | DateTime | 날짜와 시간 표현, 생성, 조작 | DateTime.now(), DateTime(2024, 5, 15, 14, 30) |
Duration | 시간 차이 표현, 더하기/빼기 | Duration(days: 3), Duration(hours: 2) | |
날짜/시간 생성 및 읽기 | DateTime.now() | 현재 날짜/시간 가져오기 | print(DateTime.now()) |
DateTime.utc() | UTC 기준 날짜/시간 생성 | DateTime.utc(2024, 5, 15) | |
date.year, date.month | 연, 월, 일 정보 읽기 | date.year | |
date.day, date.hour, date.minute | 일, 시, 분 정보 읽기 | date.day | |
날짜/시간 포맷 | intl 패키지의 DateFormat | 날짜 문자열 포맷팅 | DateFormat('yyyy-MM-dd').format(date) |
날짜 연산 | date.add(Duration(days: 5)) | 날짜 더하기 | date.subtract(Duration(days: 3)) |
date.isBefore(), date.isAfter() | 날짜 비교 | date1.isBefore(date2) | |
날짜 차이 계산 | (date2.difference(date1)).inDays | 두 날짜 차이 일수 계산 | DateTime.now().difference(otherDate).inDays |
시간 포맷팅 | intl 패키지의 DateFormat | 문자열로 시간 포맷팅 | DateFormat('HH:mm').format(date) |
시간 계산 | Duration 활용 | 시간 더하기/빼기 | duration = Duration(hours: 1); date.add(duration) |
힙합/캘린더 위젯 | table_calendar 패키지 | Flutter 달력 위젯 제공 | TableCalendar() |
CalendarDatePicker | Flutter 내장 날짜 선택 위젯 | CalendarDatePicker() | |
CupertinoDatePicker | iOS 스타일 날짜/시간 선택기 | CupertinoDatePicker() | |
달력 속성 | focusedDay | 현재 보여지는 날짜 중심 | focusedDay: DateTime.now() |
selectedDayPredicate | 선택된 날짜 표시 조건 | (day) => isSameDay(selectedDay, day) | |
firstDay, lastDay | 선택 가능한 날짜 범위 | firstDay: DateTime(2000), lastDay: DateTime(2100) | |
weekDayStyle, headerStyle | 달력 스타일 커스터마이징 | headerStyle: HeaderStyle() | |
달력 이벤트 및 표시 | Event 클래스, 이벤트 리스트 | 특정 날짜에 이벤트 연결 | Map<DateTime, List<Event>> |
valueNotifier | 선택된 날짜/이벤트 상태 저장 | ValueNotifier<List<Event>> | |
기타 유용 함수 및 속성 | isSameDay() | 두 날짜가 같은지 비교 | isSameDay(date1, date2) |
format() | 날짜를 문자열로 포맷팅 | DateFormat('yyyy-MM-dd').format(date) | |
toLocal(), toUtc() | 시간대 변환 | date.toUtc(), date.toLocal() |
3. 예시 코드 (간단한 달력 만들기)
.dart
더보기
import 'package:flutter/material.dart';
import 'package:table_calendar/table_calendar.dart';
class CalendarPage extends StatefulWidget {
@override
_CalendarPageState createState() => _CalendarPageState();
}
class _CalendarPageState extends State<CalendarPage> {
late final ValueNotifier<List<Event>> _selectedEvents;
CalendarFormat _calendarFormat = CalendarFormat.month;
DateTime _focusedDay = DateTime.now();
DateTime? _selectedDay;
@override
void initState() {
super.initState();
_selectedDay = _focusedDay;
_selectedEvents = ValueNotifier(_getEventsForDay(_selectedDay!));
}
@override
void dispose() {
_selectedEvents.dispose();
super.dispose();
}
List<Event> _getEventsForDay(DateTime day) {
// 이벤트 데이터를 가져오는 로직 또는 테스트용 더미 데이터
return kEvents[day] ?? [];
}
@override
Widget build(BuildContext context) {
return Scaffold(
// 전체 깔끔한 배경 없이 달력만 보여주는 구조
body: Column(
children: [
TableCalendar<Event>(
firstDay: DateTime.utc(2000, 1, 1),
lastDay: DateTime.utc(2100, 12, 31),
focusedDay: _focusedDay,
calendarFormat: _calendarFormat,
selectedDayPredicate: (day) => isSameDay(_selectedDay, day),
onDaySelected: (selectedDay, focusedDay) {
setState(() {
_selectedDay = selectedDay;
_focusedDay = focusedDay; // 뷰 포커스 이동
_selectedEvents.value = _getEventsForDay(selectedDay);
});
},
onFormatChanged: (format) {
setState(() {
_calendarFormat = format;
});
},
onPageChanged: (focusedDay) {
_focusedDay = focusedDay;
},
// 달력 스타일 커스터마이즈 가능
calendarStyle: CalendarStyle(
todayDecoration: BoxDecoration(
color: Colors.blueAccent,
shape: BoxShape.circle,
),
selectedDecoration: BoxDecoration(
color: Colors.orange,
shape: BoxShape.circle,
),
),
// 헤더 스타일 커스터마이즈
headerStyle: HeaderStyle(
formatButtonVisible: false,
titleCentered: true,
),
),
],
),
);
}
}
// 이벤트 데이터 구조
class Event {
final String title;
const Event(this.title);
@override
String toString() => title;
}
// 더미 이벤트 데이터
final Map<DateTime, List<Event>> kEvents = {
DateTime.utc(2025, 5, 15): [Event('이벤트 1')],
DateTime.utc(2025, 5, 20): [Event('이벤트 2')],
DateTime.utc(2025, 6, 10): [Event('이벤트 3')],
};
4. 코드 해설
- StatefulWidget: 날짜 선택 등 상태 변화가 있는 UI 구성
- TableCalendar: 실제 달력을 구성하는 핵심 위젯
- onDaySelected: 날짜 선택 시 동작 정의 (setState()로 상태 갱신)
- selectedDayPredicate: 선택된 날짜를 강조 표시
- intl: 선택한 날짜를 보기 좋게 포맷
- DateTime.utc()는 UTC 시간(전 세계 표준시) 기준으로 생성됩니다.
- DateTime()은 기기 또는 시스템의 로컬 타임존 기준으로 생성됩니다.
참고
'Flutter + Dart > Flutter + Dart 공부' 카테고리의 다른 글
애니메이션 기초 학습 및 플랫폼별 UI 이해 (0) | 2025.05.16 |
---|---|
테마 및 스타일 적용, 커스텀 위젯 제작 기초 (0) | 2025.05.16 |
Provider (0) | 2025.05.15 |
스크롤과 페이지 네비게이션 가이드 (1) | 2025.05.14 |
리스트뷰 및 그리드뷰 학습, 상태 관리 소개 (StatefulWidget) (0) | 2025.05.14 |