Flutterでカレンダー表示したいときに一番ポビュラーそうなパッケージがtable_calenderだったので、その使い方の調査。
basic exampleを見ながら使い方調査
- firstDay : カレンダーの範囲の開始日。それ以前の日にはユーザーはアクセスできない。
- lastDay : カレンダー範囲の最後の日。それ以降にはユーザーアクセスできない。
- focuedDay : 最初のターゲットの日にち
selectedDayPredicate
selectedDayPredicate: (day) {
bool isSameFlag = isSameDay(_selectedDay, day);
print('${day.month}/${day.day} ,SameDay :$isSameFlag');
return isSameDay(_selectedDay, day);
},
onDaySelected: (selectedDay, focusedDay) {
print('onSelect!!');
if (!isSameDay(_selectedDay, selectedDay)) {
// Call `setState()` when updating the selected day setState(() {
_selectedDay = selectedDay;
_focusedDay = focusedDay;
});
}
},
I/flutter (11992): onSelect!!
I/flutter (11992): 2/10 ,SameDay :false
I/flutter (11992): 2/1 ,SameDay :false
I/flutter (11992): 2/2 ,SameDay :true
I/flutter (11992): 2/3 ,SameDay :false
I/flutter (11992): 2/4 ,SameDay :false
I/flutter (11992): 2/5 ,SameDay :false
I/flutter (11992): 2/6 ,SameDay :false
I/flutter (11992): 2/7 ,SameDay :false
I/flutter (11992): 2/8 ,SameDay :false
I/flutter (11992): 2/9 ,SameDay :false
I/flutter (11992): 1/30 ,SameDay :false
I/flutter (11992): 2/11 ,SameDay :false
I/flutter (11992): 2/12 ,SameDay :false
I/flutter (11992): 2/13 ,SameDay :false
I/flutter (11992): 2/14 ,SameDay :false
I/flutter (11992): 2/15 ,SameDay :false
I/flutter (11992): 2/16 ,SameDay :false
I/flutter (11992): 2/17 ,SameDay :false
I/flutter (11992): 2/18 ,SameDay :false
I/flutter (11992): 2/19 ,SameDay :false
I/flutter (11992): 2/20 ,SameDay :false
I/flutter (11992): 2/21 ,SameDay :false
I/flutter (11992): 1/31 ,SameDay :false
I/flutter (11992): 2/23 ,SameDay :false
I/flutter (11992): 2/24 ,SameDay :false
I/flutter (11992): 2/25 ,SameDay :false
I/flutter (11992): 2/26 ,SameDay :false
I/flutter (11992): 2/27 ,SameDay :false
I/flutter (11992): 2/28 ,SameDay :false
I/flutter (11992): 3/1 ,SameDay :false
I/flutter (11992): 3/2 ,SameDay :false
I/flutter (11992): 3/3 ,SameDay :false
I/flutter (11992): 3/4 ,SameDay :false
I/flutter (11992): 3/5 ,SameDay :false
I/flutter (11992): 2/22 ,SameDay :false
selectedDayPredicateがどういう挙動するか不明だったんだけど、 どうやらUIのビルド走るときに?日付セルの一つ一つでチェックが走るっぽい。 これでtrueを返すと selectedみたいな挙動になる。
selectedDayPredicate: (day) {
return true;
},
カスタマイズ全部
import 'dart:collection';
import 'package:flutter/material.dart';
import 'package:netroll/constants.dart';
import 'package:table_calendar/table_calendar.dart';
import 'package:netroll/utils.dart';
class HomeTable extends StatefulWidget {
const HomeTable({Key? key}) : super(key: key);
_HomeTableState createState() => _HomeTableState();
}
class _HomeTableState extends State<HomeTable> {
CalendarFormat _calformat = CalendarFormat.month;
DateTime _focusedDay = DateTime.now();
DateTime? _selectedDay;
Map<DateTime, List> _eventList = {};
void initState() {
super.initState();
_selectedDay = _focusedDay;
_eventList = {
DateTime.now().subtract(const Duration(days: 2)): ['Event 1', 'Event 2'],
DateTime.now().add(const Duration(days: 1)): [
'Event 3 本日のタスク',
'Event 4 asd;flkjasdf',
'Event 5 hello world',
'Event 6 vomit vomit',
'Event 7 table_calendar',
'Event 8',
'Event 9',
'Event 10',
'Event 11',
'Event 12',
'Event 13',
'Event 14',
'Event 15',
'Event 16',
],
DateTime.now().add(const Duration(days: 3)):
{'Event 17', 'Event 18', 'Event 19'}.toList(),
};
}
Widget _buildEventsMarker(DateTime date, List events) {
return Positioned(
right: 5,
bottom: 5,
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.redAccent,
),
width: 16.0,
height: 16.0,
child: Center(
child: Text(
'${events.length}',
style: const TextStyle().copyWith(
color: Colors.white,
fontSize: 12.0,
),
),
),
),
);
}
Widget build(BuildContext context) {
final _events =
LinkedHashMap<DateTime, List>(equals: isSameDay, hashCode: getHashCode)
..addAll(_eventList);
List getEventForDay(DateTime day) {
return _events[day] ?? [];
}
return Scaffold(
appBar: AppBar(title: const Text("Sample Calendar",
style: TextStyle(
fontFamily: 'Raleway',
fontSize: 24))),
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TableCalendar(
locale: 'ja_JP',
firstDay: kFirstDay,
lastDay: kLastDay,
focusedDay: _focusedDay,
calendarFormat: _calformat,
headerStyle: HeaderStyle(
formatButtonVisible: true,
titleCentered: true,
formatButtonShowsNext: false,
formatButtonDecoration: BoxDecoration(
color: Colors.blue, borderRadius: BorderRadius.circular(5.0)),
formatButtonTextStyle:
const TextStyle(fontFamily: 'Raleway', color: Colors.white),
),
eventLoader: getEventForDay,
calendarBuilders: CalendarBuilders(
markerBuilder: (context, date, events) {
if (events.isNotEmpty) {
return _buildEventsMarker(date, events);
}
},
selectedBuilder: (context, day, focusedDay) {},
),
daysOfWeekStyle: DaysOfWeekStyle(
weekdayStyle: TableWeekDayStyle,
weekendStyle: TableWeekEndDayStyle),
calendarStyle: CalendarStyle(
isTodayHighlighted: true,
todayDecoration: BoxDecoration(
color: Colors.pink,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(5.0)),
selectedDecoration: BoxDecoration(
color: Colors.blue,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(5.0)),
weekendDecoration: BoxDecoration(
color: Colors.amber,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(5.0)),
holidayDecoration: BoxDecoration(
color: Colors.amber,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(5.0)),
defaultDecoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(5.0))),
selectedDayPredicate: (day) {
bool isSameFlag = isSameDay(_selectedDay, day);
print('${day.month}/${day.day} ,SameDay :$isSameFlag');
return isSameDay(_selectedDay, day);
},
onDaySelected: (selectedDay, focusedDay) {
print('onSelect!!');
if (!isSameDay(_selectedDay, selectedDay)) {
// Call `setState()` when updating the selected day
setState(() {
_selectedDay = selectedDay;
_focusedDay = focusedDay;
});
getEventForDay(selectedDay);
}
},
onFormatChanged: (format) {
if (_calformat != format) {
// Call `setState()` when updating calendar format
setState(() {
_calformat = format;
});
}
},
onPageChanged: (focusedDay) {
// No need to call `setState()` here
_focusedDay = focusedDay;
},
),
Expanded(
child: ListView(
shrinkWrap: true,
children: getEventForDay(_selectedDay!)
.map((e) => Container(
decoration: const BoxDecoration(
color: Colors.blue,
border: Border(bottom: BorderSide( color: Colors.white ))
),
child: ListTile(
leading: const Icon(Icons.alarm,color: Colors.white,),
title: Text(e.toString(),style: const TextStyle(fontFamily: 'Raleway', color: Colors.white),),
),
))
.toList(),
)),
],
)),
);
}
}