-
[ Flutter ] TableCalendar 달력 커스텀Application/Flutter 2024. 6. 16. 17:30반응형
headerStyle
https://pub.dev/documentation/table_calendar/latest/table_calendar/HeaderStyle/HeaderStyle.html
HeaderStyle constructor - HeaderStyle - table_calendar library - Dart API
HeaderStyle constructor const HeaderStyle({ bool titleCentered = false, bool formatButtonVisible = true, bool formatButtonShowsNext = true, TextFormatter? titleTextFormatter, TextStyle titleTextStyle = const TextStyle(fontSize: 17.0), TextStyle formatButto
pub.dev
Implementation
- title implementation
titleCentered <boolean> : 월 표시인 '2024년 6월' 표시된 부분을 가운데 위치 여부
titleTextFormatter<TextFormatter> : title 의 날짜 형태 변경
(ex : titleTextFormatter: (date, locale) => DateFormat.yM(locale).format(date),)
titleTextStyle<TextStyle> : title style 변경
- formatButton implementation
formatButtonVisible<boolean> : 첫 TableCalendar를 사용할때 2weeks가 적혀있는 button의 노출 여부
formatButtonShowsNext<boolean> : formatButton 글자 제어 여부
formatButtonTextStyle<TextStyle> : formatButton 글자 style 변경
formatButtonDecoration<BoxDecoration> : formatButton style
formatButtonPadding<EdgeInsets> : formatButton padding
- header implementation
headerMargin<EdgeInsets> : header margin
headerPadding<EdgeInsets> : header padding
decoration<BoxDecoration> : header Style
- chevron implementaion
calendar에서 양쪽 화살표의 padding, margin, icon 지정 및 노출 여부
leftChevronPadding<EdgeInsets>
rightChevronPadding<EdgeInsets>
leftChevronMargin<EdgeInsets>
rightChevronMargin<EdgeInsets>
leftChevronIcon<EdgeInsets>
rightChevronIcon<EdgeInsets>leftChevronVisible<boolean>
rightChevronVisible<boolean>
const HeaderStyle({ this.titleCentered = false, this.formatButtonVisible = true, this.formatButtonShowsNext = true, this.titleTextFormatter, this.titleTextStyle = const TextStyle(fontSize: 17.0), this.formatButtonTextStyle = const TextStyle(fontSize: 14.0), this.formatButtonDecoration = const BoxDecoration( border: const Border.fromBorderSide(BorderSide()), borderRadius: const BorderRadius.all(Radius.circular(12.0)), ), this.headerMargin = const EdgeInsets.all(0.0), this.headerPadding = const EdgeInsets.symmetric(vertical: 8.0), this.formatButtonPadding = const EdgeInsets.symmetric(horizontal: 10.0, vertical: 4.0), this.leftChevronPadding = const EdgeInsets.all(12.0), this.rightChevronPadding = const EdgeInsets.all(12.0), this.leftChevronMargin = const EdgeInsets.symmetric(horizontal: 8.0), this.rightChevronMargin = const EdgeInsets.symmetric(horizontal: 8.0), this.leftChevronIcon = const Icon(Icons.chevron_left), this.rightChevronIcon = const Icon(Icons.chevron_right), this.leftChevronVisible = true, this.rightChevronVisible = true, this.decoration = const BoxDecoration(), });
우선 날짜 표시만 가운데로 하고 formatButton 노출만 안하도록 적용
return Container( child: TableCalendar( locale: 'ko_KR', focusedDay: _focusedDay, firstDay: DateTime.utc(focusedDay.year, focusedDay.month - 3, focusedDay.day), lastDay: DateTime.utc(focusedDay.year, focusedDay.month + 3, focusedDay.day), headerStyle: HeaderStyle( titleCentered: true, formatButtonVisible: false ),
SelectedDay
https://pub.dev/documentation/table_calendar/latest/table_calendar/OnDaySelected.html
OnDaySelected typedef - table_calendar library - Dart API
OnDaySelected typedef OnDaySelected = void Function(DateTime selectedDay, DateTime focusedDay) Signature for onDaySelected callback. Contains the selected day and focused day. Implementation typedef OnDaySelected = void Function( DateTime selectedDay, Date
pub.dev
날짜 초기화
DateTime selectedDay = DateTime( DateTime.now().year, DateTime.now().month, DateTime.now().day, ); DateTime _focusedDay = focusedDay;
onDaySelected는 날짜를 선택하면 selectedDay값과 focusedDay값을 받을 수 있는데,
두개의 값을 출력해본결과 둘다 클릭한 날짜의 값이 나와서 좀 더 해봐야할 것 같음.
selectedDayPredicate는 아직 어떨때 사용하는지를 정확하게 파악을 못함.
일단 선택한 날짜의 true false값을 return해주어서 CalendarBuilder에서
selectedBuilder가 여기서 return된 true, falser값으로 스타일을 적용 하는지 아닌지를 판단하는 것 같음.
onDaySelected: (DateTime selectedDay, DateTime focusedDay) { setState((){ this.selectedDay = selectedDay; this._focusedDay = focusedDay; }); }, selectedDayPredicate: (DateTime day) { return isSameDay(selectedDay, day); },
반응형CalendarBuilder
https://pub.dev/documentation/table_calendar/latest/table_calendar/CalendarBuilders-class.html
CalendarBuilders class - table_calendar library - Dart API
CalendarBuilders class Class containing all custom builders for TableCalendar. Constructors CalendarBuilders({FocusedDayBuilder? prioritizedBuilder, FocusedDayBuilder? todayBuilder, FocusedDayBuilder? selectedBuilder, FocusedDayBuilder? rangeStartBuilder,
pub.dev
기존의 calendar에서 날짜 표시가 1일, 2일 이런식으로 표시가 되어서 날짜 숫자만 표시되도록 변경한 후
선택한 날짜 표기 및 오늘 날짜의 색상 변경
return Container( child: TableCalendar( locale: 'ko_KR', focusedDay: _focusedDay, firstDay: DateTime.utc(focusedDay.year, focusedDay.month - 3, focusedDay.day), lastDay: DateTime.utc(focusedDay.year, focusedDay.month + 3, focusedDay.day), headerStyle: HeaderStyle( titleCentered: true, formatButtonVisible: false ), calendarBuilders: CalendarBuilders( outsideBuilder: BuildOutSideDay, defaultBuilder: BuildDefaultDay, selectedBuilder: BuildSelectedDay, todayBuilder: BuildToday, ),
outsideBuilder : 현재달이 아닌 이전 및 다음달의 날짜 표기 방식 및 스타일
defaultBuilder : 현재달 날짜 표기 방식 및 스타일
selectedBuilder : 선택한 날짜 표기 방식 및 스타일
todayBuilder : 오늘 날짜 표기 방식 및 스타일
Widget BuildOutSideDay(BuildContext context, DateTime date, DateTime focusedDay) { return Center( child: Text( '${date.day}', style: TextStyle( color: Colors.grey ), ), ); } Widget BuildDefaultDay(BuildContext context, DateTime date, DateTime focusedDay) { return Center( child: Text( '${date.day}', style: TextStyle( color: isSameDay(date, focusedDay) ? Colors.blue : Colors.black, ), ), ); } Widget BuildSelectedDay(BuildContext context, DateTime date, DateTime focusedDay) { return Center( child: Text( '${date.day}', style: TextStyle(color: Colors.green), ), ); } Widget BuildToday(BuildContext context, DateTime date, DateTime focusedDay) { return Center( child: Text( '${date.day}', style: TextStyle( color: Colors.blue, fontWeight: FontWeight.bold, ), ), ); }
아직 마커를 찍었지만 좀 더 마커 사용법을 익히고 해봐야할듯 함.
전체 코드는 이렇게 되어있음.
생각보다 코드가 길어지면서 calendar관련 변수들을 따로 파일로 만들어서 import하여 관리
특히 builder부분이 너무 많음..
import 'package:flutter/material.dart'; import 'package:table_calendar/table_calendar.dart'; import '../../utils/calendar_utils.dart'; class CalendarComponent extends StatefulWidget { @override State<CalendarComponent> createState() => _CalendarComponentState(); } class _CalendarComponentState extends State<CalendarComponent> { List<Event> _getEventsForDay(DateTime day) { return events[day] ?? []; } DateTime selectedDay = DateTime( DateTime.now().year, DateTime.now().month, DateTime.now().day, ); DateTime _focusedDay = focusedDay; @override Widget build(BuildContext context) { return Container( child: TableCalendar( locale: 'ko_KR', focusedDay: _focusedDay, firstDay: DateTime.utc(focusedDay.year, focusedDay.month - 3, focusedDay.day), lastDay: DateTime.utc(focusedDay.year, focusedDay.month + 3, focusedDay.day), eventLoader: _getEventsForDay, onDaySelected: (DateTime selectedDay, DateTime focusedDay) { setState((){ this.selectedDay = selectedDay; this._focusedDay = focusedDay; }); }, selectedDayPredicate: (DateTime day) { return isSameDay(selectedDay, day); }, calendarBuilders: CalendarBuilders( outsideBuilder: BuildOutSideDay, defaultBuilder: BuildDefaultDay, selectedBuilder: BuildSelectedDay, todayBuilder: BuildToday, ), headerStyle: HeaderStyle( titleCentered: true, formatButtonVisible: false ), calendarStyle: CalendarStyle( canMarkersOverflow: false, markerSize: 10.0, markersAnchor: 0.7, markerMargin: const EdgeInsets.symmetric(horizontal: 0.3), markersAlignment: Alignment.bottomCenter, markersMaxCount: 4, markerDecoration: const BoxDecoration( color: Colors.black, shape: BoxShape.circle ), ), ), ); } }
import 'package:flutter/material.dart'; import 'package:table_calendar/table_calendar.dart'; class Event { String title; Event(this.title); } Map<DateTime, List<Event>> events = { DateTime.utc(2024,6,13) : [ Event('title'), Event('title2') ], DateTime.utc(2024,6,14) : [ Event('title3') ], }; DateTime focusedDay = DateTime.now(); Widget BuildOutSideDay(BuildContext context, DateTime date, DateTime focusedDay) { return Center( child: Text( '${date.day}', style: TextStyle( color: Colors.grey ), ), ); } Widget BuildDefaultDay(BuildContext context, DateTime date, DateTime focusedDay) { return Center( child: Text( '${date.day}', style: TextStyle( color: isSameDay(date, focusedDay) ? Colors.blue : Colors.black, ), ), ); } Widget BuildSelectedDay(BuildContext context, DateTime date, DateTime focusedDay) { return Center( child: Text( '${date.day}', style: TextStyle(color: Colors.green), ), ); } Widget BuildToday(BuildContext context, DateTime date, DateTime focusedDay) { return Center( child: Text( '${date.day}', style: TextStyle( color: Colors.blue, fontWeight: FontWeight.bold, ), ), ); }
728x90반응형'Application > Flutter' 카테고리의 다른 글
[ Flutter ] Flutter Color 관리 (0) 2024.06.30 [ Flutter ] Animation Navigation Bar (0) 2024.06.30 [ Flutter ] Border, Color Style 및 Layout 설정 (0) 2024.06.26 [ Flutter ] TableCalendar TextMarker, 요일 색상 변경 (0) 2024.06.23 [Flutter] TableCalendar 달력 구현 (0) 2024.06.09