반응형
flutter에서 table calendar를 provider를 이용하는 방법에 대해서 알아보겠다.
stateful widget에서 사용하는 예제는 table calendar github 예제에 이미 나와있다.
https://github.com/aleksanderwozniak/table_calendar/tree/master/example
이 포스팅에서는 provider 패턴에서 table calendar 사용하는 방법을 알아볼 것이다.
화면부분은 세부분으로 나뉜다. 첫번째는 monthscreen 전체 위젯을 배열해줬다. 이 부분은 모두 알것이므로 설명을 패스하겠다.
class MonthScreen extends StatelessWidget {
const MonthScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [SizedBox(height: 8.0), Tablecalendar(), Eventlist()],
));
}
}
두번째 부분은 table calendar 부분이다. 좀 자세히 설명하겠다.
class Tablecalendar extends StatelessWidget {
late calendarModel calendarmodel;
Tablecalendar({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
calendarmodel = Provider.of<calendarModel>(context);
Model 부분에서 데이터를 가져와야하므로 provider 선언을 해준다. 그리고 tablecalendar 위젯을 리턴해준다.
return Column(
children: [
TableCalendar<EventModel>(
locale: Localizations.localeOf(context).languageCode,
여기서 한국어로 사용하려면
pubspec.yaml 파일의 dependencies부분에
flutter_localizations:
sdk: flutter
를 작성하고 컨트롤 s로 저장해서 패키지를 다운받고,
main 의 materialapp 부분에 아래와 같이 localizationsDelegates~~, supportedLocales~~를 추가해줘야한다.
child: MaterialApp(
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
],
supportedLocales: [
const Locale('en', ''), // English, no country code
const Locale('ko', ''),
],
title: 'App',
...
하여튼 그 다음에, table calendar 내부의 변수들에 대해서 데이터를 가져와야하는 것들은 Model 부분에서 가져와준다.
firstDay: kToday,
lastDay: kLastDay,
focusedDay: calendarmodel.focusedDay,
selectedDayPredicate: (day) =>
isSameDay(calendarmodel.selectedDay, day),
onDaySelected: calendarmodel.onDaySelected,
eventLoader: calendarmodel.getEventsForDay,
화면 부분의 전체 소스코드이다.
class MonthScreen extends StatelessWidget {
const MonthScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [SizedBox(height: 8.0), Tablecalendar(), Eventlist()],
));
}
}
//table calendar 시작
class Tablecalendar extends StatelessWidget {
//provider 정의
late calendarModel calendarmodel;
Tablecalendar({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
//provider 정의
calendarmodel = Provider.of<calendarModel>(context);
return Column(
children: [
TableCalendar<EventModel>(
locale: Localizations.localeOf(context).languageCode,
headerStyle: HeaderStyle(
formatButtonVisible: false,
titleCentered: true,
leftChevronVisible: false,
rightChevronVisible: false),
firstDay: kToday,
lastDay: kLastDay,
//focusedDay, selectedDay는 provider에서 값을 가져다쓰고 업데이트함.
focusedDay: calendarmodel.focusedDay,
selectedDayPredicate: (day) =>
isSameDay(calendarmodel.selectedDay, day),
//선택 날짜가 바뀔경우
onDaySelected: calendarmodel.onDaySelected,
calendarFormat: CalendarFormat.month,
//event loader
eventLoader: calendarmodel.getEventsForDay,
startingDayOfWeek: StartingDayOfWeek.monday,
calendarStyle: CalendarStyle(
isTodayHighlighted: true,
outsideDaysVisible: false,
markerDecoration: BoxDecoration()),
calendarBuilders:
CalendarBuilders(markerBuilder: (context, date, dynamic event) {
if (event.isNotEmpty) {
return Container(
width: 35,
decoration: BoxDecoration(
color: Colors.blue.withOpacity(0.2),
shape: BoxShape.circle),
);
}
})),
SizedBox(height: 8.0),
],
);
}
}
class Eventlist extends StatelessWidget {
late calendarModel calendarmodel;
Eventlist({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
calendarmodel = Provider.of<calendarModel>(context);
return Expanded(
child: Column(
children: [
ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: calendarmodel.selectedEvents.length,
itemBuilder: (context, index) {
return Container(
margin: const EdgeInsets.symmetric(
horizontal: 12.0,
vertical: 4.0,
),
decoration: BoxDecoration(
border: Border.all(),
borderRadius: BorderRadius.circular(12.0),
),
child: ListTile(
onTap: () => print(calendarmodel.selectedEvents[index]),
title: Text(calendarmodel.selectedEvents[index].toString()),
),
);
})
],
),
);
}
}
모델부분의 전체 소스 코드이다.
class EventModel extends ChangeNotifier {
String title;
EventModel(this.title);
@override
String toString() => title;
}
final kToday = DateTime.now().toLocal();
final kFirstDay = DateTime(kToday.year, kToday.month - 3, kToday.day);
final kLastDay = DateTime(kToday.year, kToday.month + 3, kToday.day);
int getHashCode(DateTime key) {
return key.day * 1000000 + key.month * 10000 + key.year;
}
class calendarModel extends ChangeNotifier {
DateTime _focusedDay = DateTime.now().toUtc();
DateTime? _selectedDay;
List<EventModel>? _selectedEvents;
final _events = LinkedHashMap<DateTime, List<EventModel>> (
equals:isSameDay,
hashCode: getHashCode)..addAll({
DateTime.utc(2022, 06, 07): [EventModel('hi')],
DateTime.utc(2022, 06, 08): [EventModel('hi')]
});
get focusedDay => _focusedDay;
get selectedDay => _selectedDay;
get selectedEvents => _selectedEvents;
get onDaySelected => _onDaySelected;
get events => _events;
get getEventsForDay => _getEventsForDay;
calendarModel() {
_selectedDay = _focusedDay.toUtc();
_selectedEvents = _events[_selectedDay?.toUtc()]??[];
notifyListeners();
}
_onDaySelected(DateTime selectedDay, DateTime focusedDay) {
if (!isSameDay(_selectedDay, selectedDay)) {
_selectedDay = selectedDay;
_focusedDay = focusedDay;
notifyListeners();
}
_selectedEvents = _events[_selectedDay]??[];
notifyListeners();
}
List<EventModel> _getEventsForDay(DateTime day) {
return _events[day] ?? [];
}
}
설명하기가 너무 어렵다,,,ㅠ
혹시 이해가 안가거나 질문이 있으면 댓글로 남겨주셔요,,,
반응형
'flutter' 카테고리의 다른 글
provider listview builder에 적용시 문제점 (0) | 2022.06.15 |
---|---|
flutter quill editor provider 적용/ 저장했던 글 불러오기 (0) | 2022.06.14 |
emulator에서 앱 삭제하기 (0) | 2022.06.04 |
flutter int to bool (0) | 2022.06.01 |
flutter error - Error launching application on sdk gphone64 arm64 (0) | 2022.06.01 |