이 전 글(Step 3rd)에서 달력의 기본 디자인을 커스터마이징 했습니다.
이제부터는 달력에 날짜 선택시 선택된 날짜에 대한 표시와 콜백함수의 틀을 작성해 보도록 하겠습니다.
TableCalendar 날짜 선택
TableCalendar 위젯은 날짜가 선택될 때마다 실행되는 콜백 함수를 등록하고 추가적으로 어떤 날짜가 현재 선택된 상태인지 달력에 표시해주어야 합니다.
HomeScreen에서 모든 상태를 관리하기 위해 MainCalendar에 코드를 작성해 보겠습니다.
lib/component/main_calendar.dart
import 'package:flutter/material.dart';
import 'package:planner_example/const/colors.dart';
import 'package:table_calendar/table_calendar.dart';
class MainCalendar extends StatelessWidget {
final DateTime selectedDay; // 선택된 날짜
final OnDaySelected onDaySelected; // 날짜 선택 콜백
const MainCalendar({
super.key,
required this.selectedDay,
required this.onDaySelected,
});
@override
Widget build(BuildContext context) {
return TableCalendar(
focusedDay: DateTime.now(), // 현재 날짜
firstDay: DateTime.now().subtract(const Duration(days: 3650)), // 첫 번째 날짜
lastDay: DateTime.now().add(const Duration(days: 3650)), // 마지막 날짜
headerStyle: HeaderStyle(
// 헤더 스타일 설정
titleCentered: true, // 제목을 중앙에 배치
formatButtonVisible: false, // 형식 버튼 숨김
titleTextStyle: const TextStyle(
// 제목 텍스트 스타일 설정
fontSize: 16.0,
fontWeight: FontWeight.w700,
),
),
calendarStyle: CalendarStyle(
// 달력 스타일 설정
defaultDecoration: BoxDecoration(
// 기본 날짜 장식
color: lightGrayColor,
borderRadius: BorderRadius.circular(6.0),
),
weekendDecoration: BoxDecoration(
// 주말 날짜 장식
color: lightGrayColor,
borderRadius: BorderRadius.circular(6.0),
),
todayDecoration: BoxDecoration(
// 오늘 날짜 장식
color: primaryColor,
borderRadius: BorderRadius.circular(6.0),
),
selectedDecoration: BoxDecoration(
// 선택된 날짜 장식
borderRadius: BorderRadius.circular(6.0),
border: Border.all(
color: primaryColor, // 선택된 날짜 테두리 색상
width: 1.0,
),
),
selectedTextStyle: TextStyle(
// 선택된 날짜 텍스트 스타일
fontWeight: FontWeight.w600,
color: primaryColor,
),
defaultTextStyle: TextStyle(
// 기본 텍스트 스타일
fontWeight: FontWeight.w600,
color: darkGrayColor,
),
),
onDaySelected: onDaySelected,
selectedDayPredicate: (day) => day == selectedDay, // 선택된 날짜 확인
);
}
}
OnDaySelected 타입은 table_calendar 플러그인에서 기본 제공하는 typedef 입니다.
onDaySelected는 달력의 날짜가 탭될 때마다 호출됩니다.
첫 번째 매개변수에 선택된 날짜를 입력받고 두 번째 매개변수에 현재 화면에 보이는 날짜를 입력 받습니다.
selectedDayPredicate는 어떤 날짜를 선택된 날짜로 지정할지 결정하는 함수입니다.
현재 달력에 보이는 모든 날짜를 순회하며 실행하는 함수로 true가 반환되면 선택된 날짜로 표시되고 false가 반환되면 선택되지 않은 날짜로 표시됩니다.
HomeScreen에서 입력해줄 selectedDate와 같으면 선택된 날짜로 지정했습니다.
lib/screen/home_screen.dart
import 'package:flutter/material.dart';
import 'package:planner_example/component/main_calendar.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
DateTime selectedDay = DateTime.now();
void onDaySelected(DateTime selectedDay, DateTime focusedDay) {
setState(() {
this.selectedDay = selectedDay;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Home')),
body: SafeArea(
child: Column(
children: [
MainCalendar(
selectedDay: selectedDay,
onDaySelected: onDaySelected,
),
],
),
),
);
}
}
MainCalendar 위젯에 생성한 매개변수들을 HomeScreen에 입력해 줍니다.
HomeScreen 위젯은 StatefulWidget으로 전환했습니다.
선택된 날자를 관리할 selectedDate 변수와 onDaySelected() 함수를 선언해서 날짜가 탭될 때마다 selectedDate 변수를 변경합니다.
실행화면
