import 'package:booking_calendar/utils.dart';
import 'package:flutter/material.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'pages/events_example.dart';
import 'package:booking_calendar/pages/multi_example.dart';
import 'package:booking_calendar/pages/complex_example.dart';
import 'package:booking_calendar/pages/basics_example.dart';
import 'package:booking_calendar/pages/range_example.dart';
import 'package:provider/provider.dart';
void main() {
initializeDateFormatting().then((_) => runApp(MyApp()));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'TableCalendar Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: StartPage(),
);
}
}
class StartPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<EventData>(
create: (context) => EventData(),
child: Scaffold(
appBar: AppBar(
title: const Text('Table Calendar'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(height: 20.0),
ElevatedButton(
child: const Text('Basics'),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(builder: (_) => TableBasicsExample()),
),
),
const SizedBox(height: 12.0),
ElevatedButton(
child: Text('Multiple Selection'),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(builder: (_) => TableMultiExample()),
),
),
const SizedBox(height: 20.0),
],
),
),
),
);
}
}
import 'dart:collection';
import 'package:table_calendar/table_calendar.dart';
import 'package:flutter/foundation.dart';
import 'package:booking_calendar/data/event.dart';
/// Example event class.
class EventData extends ChangeNotifier{
late var kToday = DateTime.now();
late var kFirstDay = DateTime(kToday.year, kToday.month - 6, kToday.day);
late var kLastDay = DateTime(kToday.year, kToday.month + 6, kToday.day);
/// Example events.
///
/// Using a [LinkedHashMap] is highly recommended if you decide to use a map.
late var kEvents = LinkedHashMap<DateTime, List<Event>>(
equals: isSameDay,
hashCode: getHashCode,
)..addAll(kEventSource1);
/// Example events.
///
/// Using a [LinkedHashMap] is highly recommended if you decide to use a map.
// Keep data as List
late var kEventSource1 = Map.fromIterables(kDay, events);
List<DateTime> kDay = [DateTime.utc(2023, 6, 6), DateTime.utc(2023, 6, 7)];
List<List<Event>> events = [
[Event('Test1'), Event('Test2')],
[Event('Test3')],
];
void addEvent(Set<DateTime> selectedDays, String newEvents) {
List<DateTime> kDays = [];
kDays = selectedDays.toList();
kDay.addAll(kDays);
List<Event> event = [];
var kEvent = Event(newEvents);
event.add(kEvent);
events.add(event);
notifyListeners();
}
int getHashCode(DateTime key) {
return key.day * 1000000 + key.month * 10000 + key.year;
}
/// Returns a list of [DateTime] objects from [first] to [last], inclusive.
List<DateTime> daysInRange(DateTime first, DateTime last) {
final dayCount = last.difference(first).inDays + 1;
return List.generate(
dayCount,
(index) => DateTime.utc(first.year, first.month, first.day + index),
);
}
}
class Event{
// List<DateTime>? eventDate;
List<List<String>>? eventName;
final String title;
@override
String toString() => title;
Event(this.title, {this.eventName});
}
import 'dart:collection';
import 'package:flutter/material.dart';
import 'package:table_calendar/table_calendar.dart';
import 'package:provider/provider.dart';
import 'package:booking_calendar/utils.dart';
import 'package:booking_calendar/data/event.dart';
class TableMultiExample extends StatefulWidget {
@override
_TableMultiExampleState createState() => _TableMultiExampleState();
}
class _TableMultiExampleState extends State<TableMultiExample> {
late String newEvents;
var eventData = EventData();
final ValueNotifier<List<Event>> _selectedEvents = ValueNotifier([]);
// Using a `LinkedHashSet` is recommended due to equality comparison override
late Set<DateTime> _selectedDays = LinkedHashSet<DateTime>(
equals: isSameDay,
hashCode: eventData.getHashCode,
);
CalendarFormat _calendarFormat = CalendarFormat.month;
DateTime _focusedDay = DateTime.now();
@override
void dispose() {
_selectedEvents.dispose();
super.dispose();
}
List<Event> _getEventsForDay(DateTime day) {
// Implementation example
return eventData.kEvents[day] ??[];
}
List<Event> _getEventsForDays(Set<DateTime> days) {
// Implementation example
// Note that days are in selection order (same applies to events)
return [
for (final d in days) ...?_getEventsForDay(d),
];
}
void _onDaySelected(DateTime selectedDay, DateTime focusedDay) {
setState(() {
_focusedDay = focusedDay;
// Update values in a Set
if (_selectedDays.contains(selectedDay)) {
_selectedDays.remove(selectedDay);
} else {
_selectedDays.add(selectedDay);
}
});
_selectedEvents.value = _getEventsForDays(_selectedDays);
}
// This is example function used for adding event
void _showAddDialog() {
showDialog(
context: context,
builder: (context) => AlertDialog(
backgroundColor: Colors.white70,
title: const Text("Add Events"),
content: TextField(
decoration: const InputDecoration(
icon: Icon(
Icons.add_comment,
color: Colors.lightBlueAccent,
),
enabledBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: Colors.lightBlueAccent, width: 2.0),
),
labelText: 'Add new event here.',
labelStyle: TextStyle(fontSize: 15.0),
),
onChanged: (String newEvent) {
newEvents = newEvent;
},
),
actions: <Widget>[
TextButton(
child: const Text(
"Add",
style: TextStyle(
color: Colors.red, fontWeight: FontWeight.bold),
),
onPressed: () {
var provider = Provider.of<EventData>(context, listen: false);
provider.addEvent(_selectedDays, newEvents);
Navigator.pop(context);
},
)
],
));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('TableCalendar - Multi'),
),
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.black,
onPressed: _showAddDialog,
child: const Icon(Icons.add),
),
body: Column(
children: [
TableCalendar<Event>(
firstDay: eventData.kFirstDay,
lastDay: eventData.kLastDay,
focusedDay: _focusedDay,
calendarFormat: _calendarFormat,
eventLoader: _getEventsForDay,
startingDayOfWeek: StartingDayOfWeek.monday,
selectedDayPredicate: (day) {
// Use values from Set to mark multiple days as selected
return _selectedDays.contains(day);
},
// To display event as number.
calendarStyle:
CalendarStyle(markersAlignment: Alignment.bottomRight),
calendarBuilders: CalendarBuilders(
markerBuilder: (context, _focusedDay, _selectedEvents) =>
_selectedEvents.isNotEmpty
? Container(
width: 24,
height: 24,
alignment: Alignment.center,
decoration: const BoxDecoration(
color: Colors.lightBlue,
),
child: Text(
'${_selectedEvents.length}',
style: const TextStyle(color: Colors.white),
),
)
: null,
),
onDaySelected: _onDaySelected,
onFormatChanged: (format) {
if (_calendarFormat != format) {
setState(() {
_calendarFormat = format;
});
}
},
onPageChanged: (focusedDay) {
_focusedDay = focusedDay;
},
),
ElevatedButton(
child: Text('Clear selection'),
onPressed: () {
setState(() {
_selectedDays.clear();
_selectedEvents.value = [];
});
},
),
const SizedBox(height: 8.0),
Expanded(
child: ValueListenableBuilder<List<Event
>>(
valueListenable: _selectedEvents,
builder: (context, value, _) {
return ListView.builder(
itemCount: value.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('${value[index]}'),
title: Text('${value[index]}'),
),
);
},
);
},
),
),
],
),
);
}
}
Below shows error.
======== Exception caught by gesture =============================================================== The following ProviderNotFoundException was thrown while handling a gesture: Error: Could not find the correct Provider above this Builder Widget
This happens because you used a BuildContext
that does not include the provider
of your choice. There are a few common scenarios:
You added a new provider in your
main.dart
and performed a hot-reload. To fix, perform a hot-restart.The provider you are trying to read is in a different route.
Providers are "scoped". So if you insert of provider inside a route, then other routes will not be able to access that provider.
You used a
BuildContext
that is an ancestor of the provider you are trying to read.Make sure that Builder is under your MultiProvider/Provider. This usually happens when you are creating a provider and trying to read it immediately.
For example, instead of:
Widget build(BuildContext context) { return Provider<Example>( create: (_) => Example(), // Will throw a ProviderNotFoundError, because `context` is associated // to the widget that is the parent of `Provider<Example>` child: Text(context.watch<Example>().toString()), ); }
consider using
builder
like so:Widget build(BuildContext context) { return Provider<Example>( create: (_) => Example(), // we use `builder` to obtain a new `BuildContext` that has access to the provider builder: (context, child) { // No longer throws return Text(context.watch<Example>().toString()); } ); }
If none of these solutions work, consider asking for help on StackOverflow: https://stackoverflow.com/questions/tagged/flutter
When the exception was thrown, this was the stack: #0 Provider._inheritedElementOf (package:provider/src/provider.dart:343:7) #1 Provider.of (package:provider/src/provider.dart:293:30) #2 _TableMultiExampleState._showAddDialog.. (package:booking_calendar/pages/multi_example.dart:118:45) #3 _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1154:21) #4 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:275:24) #5 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:654:11) #6 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:311:5) #7 BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:244:7) #8 PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:630:9) #9 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:98:12) #10 PointerRouter._dispatchEventToRoutes. (package:flutter/src/gestures/pointer_router.dart:143:9) #11 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:625:13) #12 PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:141:18) #13 PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:127:7) #14 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:465:19) #15 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:445:22) #16 RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:331:11) #17 GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:400:7) #18 GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:363:5) #19 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:320:7) #20 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:293:9) #21 _invoke1 (dart:ui/hooks.dart:158:13) #22 PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:382:7) #23 _dispatchPointerDataPacket (dart:ui/hooks.dart:91:31) Handler: "onTap" Recognizer: TapGestureRecognizer#257e6 debugOwner: GestureDetector state: possible won arena finalPosition: Offset(301.4, 349.1) finalLocalPosition: Offset(37.1, 26.3) button: 1 sent tap down
I need to add new event in multi calendar with provider package.
I am a new flutter learner. Please kindly advise to fix this error, Thank you in advance.