I am trying to create a view where the user can select the agenda view he wants (day, week, month...). In my appBar, I have created an action icon where the user can select the agenda view he wants. When I change the view, the set state does not refresh the agenda view. I do not find what I am missing.
If you could help, it will be appreciated. Thank you.
import 'package:syncfusion_flutter_calendar/calendar.dart';
import 'package:provider/provider.dart';
class CalendarWidget extends StatefulWidget {
CalendarView viewCalendar;
CalendarController _controller = CalendarController();
CalendarWidget(this.viewCalendar,this._controller, {Key? key}) : super(key: key);
@override
State<CalendarWidget> createState() => _CalendarWidgetState(viewCalendar,_controller);
}
class _CalendarWidgetState extends State<CalendarWidget> {
CalendarView viewCalendar;
CalendarController _controller;
@override
_CalendarWidgetState(this.viewCalendar,this._controller);
@override
Widget build(BuildContext context) {
return Column(
children: [
myCalendar(context,viewCalendar,_controller),
const SizedBox(height: 8.0),
],
);
}
}
Widget myCalendar (BuildContext context, view,_controler ) {
final events = Provider.of<EventProvider>(context).events;
final CalendarController _calendarControler = CalendarController();
_calendarControler.view = view;
return SfCalendar(
view: CalendarView.month,
// timeSlotViewSettings:
// const TimeSlotViewSettings(allDayPanelColor: Colors.green),
controller: _controler,
_controler.view = view,
//_controller.view = CalendarView.week,
showNavigationArrow: true,
showWeekNumber: true,
showDatePickerButton: true,
showCurrentTimeIndicator: true,
initialSelectedDate: DateTime.now(),
firstDayOfWeek: 1,
dataSource: EventDataSource(events),
onSelectionChanged: (details) {
final provider = Provider.of<EventProvider>(context, listen: false);
provider.setDate(details.date!);
},
onTap: (details) {
final provider = Provider.of<EventProvider>(context, listen: false);
if (provider.selectedDate == details.date) {
showModalBottomSheet(
context: context,
builder: (context) => const TasksWidget(),
);
}
},
onLongPress: (details) {
final provider = Provider.of<EventProvider>(context, listen: false);
provider.setDate(details.date!);
showModalBottomSheet(
context: context,
builder: (context) => const TasksWidget(),
);
},
);
}
class AgendaOrganize extends StatefulWidget {
const AgendaOrganize ({Key? key}) : super(key : key);
@override
_AgendaOrganizeState createState() => _AgendaOrganizeState();
}
class _AgendaOrganizeState extends State<AgendaOrganize> {
CalendarView viewCalendar = CalendarView.month;
final CalendarController _controller = CalendarController();
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: const MyMenu(),
appBar: AppBar(
title: const Center(
child: Text('Agenda')),
actions: <Widget>[
PopupMenuButton
(icon: const Icon(Icons.more_vert_outlined),
itemBuilder: (BuildContext context) {
return Menus.choice.map((String choice){
return PopupMenuItem(
value: choice,
child: Text(choice));
}).toList();
},
onSelected:
choiceMade,
),
IconButton(
icon: const Icon(
Icons.add_circle_outline,
color: Colors.white,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const EventEditingPage()));
},
),
],),
body: CalendarWidget(viewCalendar),
//TODO //PROBLEME - SI J'AFFICHE PERSISTENTBOTTOMNAVBAR, affiche agenda FOR TODAY
// bottomNavigationBar: PersistentBottomNavBar(),
);
throw UnimplementedError();
}
@override
void setState(VoidCallback fn) {
viewCalendar = CalendarView.month;
super.setState(fn);
}
void choiceMade(String value) {
print(value);
setState(() {
viewCalendar = CalendarView.month;
});
}
}
class Menus {
static const List<String> choice = <String> [
'Day', 'Week', 'Work Week', 'Month','Schedule', 'Timeline Day', 'Timeline Week', 'Timeline Work Week'
];
}
Just add a key to the SfCalendar
and it's going to change on every setState
. Do it like the following:
Widget myCalendar(BuildContext context, CalendarView view) {
final events = Provider.of<EventProvider>(context).events;
final CalendarController _calendarControler = CalendarController();
return SfCalendar(
key: ValueKey(view), // <- Here
view: view,
...
Also, the CalendarWidget
is passing the state further down to the _CalendarWidgetState
itself. The _CalendarWidgetState
should use widget.viewCalendar
instead.
class CalendarWidget extends StatefulWidget {
CalendarView viewCalendar;
CalendarWidget(this.viewCalendar, {Key? key}) : super(key: key);
@override
State<CalendarWidget> createState() => _CalendarWidgetState();
}
class _CalendarWidgetState extends State<CalendarWidget> {
@override
Widget build(BuildContext context) {
return Column(
children: [
myCalendar(context, widget.viewCalendar),
const SizedBox(height: 8.0),
],
);
}
}
And here every choice possible:
void choiceMade(String value) {
setState(() {
switch (value) {
case 'Day':
viewCalendar = CalendarView.day;
break;
case 'Week':
viewCalendar = CalendarView.week;
break;
case 'Work Week':
viewCalendar = CalendarView.workWeek;
break;
case 'Month':
viewCalendar = CalendarView.month;
break;
case 'Schedule':
viewCalendar = CalendarView.schedule;
break;
case 'Timeline Day':
viewCalendar = CalendarView.timelineDay;
break;
case 'Timeline Week':
viewCalendar = CalendarView.timelineWeek;
break;
case 'Timeline Work Week':
viewCalendar = CalendarView.timelineWorkWeek;
break;
}
});
}