728x90
Flutter 달력 만들기 & 트러블슈팅 가이드
1. Flutter 달력 기본 구현법
1-1. TableCalendar 패키지 설치
pubspec.yaml에 다음 의존성을 추가 후 flutter pub get 실행
dependencies:
flutter:
sdk: flutter
table_calendar: ^3.0.9
intl: ^0.18.1
1-2. 기본 달력 위젯 사용법
import 'package:flutter/material.dart';
import 'package:table_calendar/table_calendar.dart';
import 'package:intl/date_symbol_data_local.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await initializeDateFormatting('ko_KR', null); // 필수 로케일 초기화
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('달력 예제')),
body: TableCalendar(
locale: 'ko_KR',
firstDay: DateTime.utc(2000, 1, 1),
lastDay: DateTime.utc(2100, 12, 31),
focusedDay: DateTime.now(),
),
),
);
}
}
- initializeDateFormatting() 호출은 한글 등 특정 로케일의 날짜/시간 포맷을 사용하기 위해 필수
- locale: 'ko_KR' 로 설정해야 한글 달력이 나온다
2. 주요 트러블슈팅
2-1. 오류: Locale data has not been initialized
- 오류 메시지:
Locale data has not been initialized, call initializeDateFormatting(<locale>). - 원인:
intl 패키지의 날짜 포맷 데이터가 초기화되지 않음. - 해결법:
main() 함수에서 비동기로 await initializeDateFormatting('ko_KR', null); 호출 후 runApp() 실행해야 함.
2-2. 렌더링 과부하(프레임 스킵 등) 문제
- 발생 상황:
달력 렌더링 시 프레임이 많이 스킵되거나 앱이 느려짐 - 원인:
불필요한 상태 업데이트, 복잡한 위젯 트리, 무거운 연산을 메인 스레드에서 처리 - 해결법:
- Stateful 위젯에서 상태 관리를 최소화
- 필요할 때만 빌드 호출
- ListView, Calendar 같은 위젯은 캐싱, 메모리 절약에 신경쓰기
- 화면 전환 등 복잡한 로직은 별도 isolate로 분리 검토
2-3. 권한 관련 오류
- 위치 권한 등 시스템 권한이 없으면 위치 기반 기능이 동작 안 함
- AndroidManifest.xml 등에서 ACCESS_FINE_LOCATION 권한 선언 필요
3. 달력과 일기 앱 예시 구조
- 달력 표시: TableCalendar를 CalendarWidget 커스텀 위젯으로 만들어 화면에 표시
- 일기 리스트: 달력 아래에 일기 리스트 출력, ListView.builder로 표시
- 일기 작성: 새 화면에서 작성 후 결과 전달받아 리스트 갱신
- 상세 보기: 일기 제목/내용 자세히 보기 화면 구현
4. 달력 위젯 간단 구현 예제
import 'package:flutter/material.dart';
import 'package:table_calendar/table_calendar.dart';
import 'package:intl/date_symbol_data_local.dart';
class CalendarWidget extends StatefulWidget {
const CalendarWidget({Key? key}) : super(key: key);
@override
State<CalendarWidget> createState() => _CalendarWidgetState();
}
class _CalendarWidgetState extends State<CalendarWidget> {
late final DateTime _focusedDay;
DateTime? _selectedDay;
@override
void initState() {
super.initState();
_focusedDay = DateTime.now();
_selectedDay = _focusedDay;
}
@override
Widget build(BuildContext context) {
return TableCalendar(
locale: 'ko_KR',
firstDay: DateTime.utc(2000, 1, 1),
lastDay: DateTime.utc(2100, 12, 31),
focusedDay: _focusedDay,
selectedDayPredicate: (day) => isSameDay(_selectedDay, day),
onDaySelected: (selectedDay, focusedDay) {
setState(() {
_selectedDay = selectedDay;
// _focusedDay = focusedDay; // 필요시 업데이트
});
},
calendarFormat: CalendarFormat.month,
);
}
}
6. 결론
- Flutter 달력 구현 시 intl 로케일 초기화가 가장 중요한 첫 단계
- 렌더링 성능 문제는 상태관리와 빌드 최소화로 해결
- 권한 문제도 사전에 반드시 확인 및 설정
- 달력과 일기 앱 구조를 잘 설계하면 기능 확장도 편리
'Flutter + Dart > 다이어리 프로젝트' 카테고리의 다른 글
일정화면 만들기 (1) | 2025.05.19 |
---|---|
다이어리 위젯 - Diary Screen (0) | 2025.05.19 |
flutter 키, 값을 가지는 리스트 만들기 (0) | 2025.05.14 |
ListView + Column 문제 (0) | 2025.05.14 |
트러블 슈팅 - Container 위젯 내에 children 속성 사용 오류 (0) | 2025.05.13 |