Related
I am implementing a calendar where I want events to be stored and that they are always available to view, currently I can store them but when I exit the application they are deleted and I can no longer see them I tried to store them in the database but they are still deleted
class control_prenatal extends StatefulWidget {
final BaseAuth auth;
const control_prenatal(this.auth);
#override
State<control_prenatal> createState() => _control_prenatalState();
}
class _control_prenatalState extends State<control_prenatal> {
CollectionReference users = FirebaseFirestore.instance.collection('dates');
late Map<DateTime, List<Event>> selectedEvents;
CalendarFormat formart = CalendarFormat.month;
DateTime selectedDay = DateTime.now();
DateTime focusedDay = DateTime.now();
final databaseRef = FirebaseDatabase.instance.ref();
var _eventController = TextEditingController();
#override
void initState() {
selectedEvents = {};
super.initState();
}
List<Event> _getEventsfromDay(DateTime date) {
return selectedEvents[date] ?? [];
}
#override
void dispose() {
_eventController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Control Prenatal'),
backgroundColor: Color.fromARGB(255, 230, 57, 137),
centerTitle: true,
),
body: SingleChildScrollView(
child: Column(
children: [
TableCalendar(
firstDay: DateTime.utc(2010, 10, 16),
lastDay: DateTime.utc(2030, 3, 14),
focusedDay: selectedDay,
calendarFormat: formart,
onFormatChanged: (CalendarFormat _formart) {
setState(() {
formart = _formart;
});
},
startingDayOfWeek: StartingDayOfWeek.sunday,
daysOfWeekVisible: true,
//Day changed
onDaySelected: (DateTime selectDay, DateTime focusDay) {
setState(() {
selectedDay = selectDay;
focusedDay = focusDay;
});
print(focusDay);
},
selectedDayPredicate: (DateTime date) {
return isSameDay(selectedDay, date);
},
eventLoader: _getEventsfromDay,
//To style the calendar
calendarStyle: CalendarStyle(
isTodayHighlighted: true,
selectedDecoration: BoxDecoration(
color: Color.fromARGB(255, 230, 57, 137),
shape: BoxShape.circle,
),
selectedTextStyle: TextStyle(color: Colors.white),
todayDecoration: BoxDecoration(
color: Colors.amber,
shape: BoxShape.circle,
),
defaultDecoration: BoxDecoration(
shape: BoxShape.circle,
),
weekendDecoration: BoxDecoration(
shape: BoxShape.circle,
),
),
headerStyle: HeaderStyle(
formatButtonVisible: true,
titleCentered: true,
formatButtonShowsNext: false,
formatButtonDecoration: BoxDecoration(
color: Color.fromARGB(255, 230, 57, 137),
borderRadius: BorderRadius.circular(5.0),
),
formatButtonTextStyle: TextStyle(
color: Colors.white,
),
leftChevronVisible: true,
rightChevronVisible: true,
headerPadding: EdgeInsets.symmetric(
horizontal: 4.0,
vertical: 5.0,
),
),
),
..._getEventsfromDay(selectedDay).map(
(Event event) => ListTile(
title: Text(event.title),
),
)
],
),
),
floatingActionButton: FloatingActionButton.extended(
onPressed: () => showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Agregar Cita'),
content: Container(
padding: const EdgeInsets.fromLTRB(30, 0, 30, 0),
child: TextField(
controller: _eventController,
decoration: const InputDecoration(
hintText: 'Nota',
labelText: 'Ingrese nota',
border: OutlineInputBorder(),
),
)),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('Cancelar')),
TextButton(
onPressed: () {
widget.auth.currentUser().then((userId) {
inserData(_eventController.text, userId);
});
if (_eventController.text.isEmpty) {
} else {
if (selectedEvents[selectedDay] != null) {
selectedEvents[selectedDay]?.add(
Event(title: _eventController.text),
);
} else {
selectedEvents[selectedDay] = [
Event(title: _eventController.text)
];
}
}
Navigator.pop(context);
_eventController.clear();
setState(() {});
return;
},
child: Text('Agendar')),
],
),
),
label: Text('Agendar Cita'),
icon: Icon(Icons.add),
backgroundColor: Color.fromARGB(255, 230, 57, 137),
),
);
}
void inserData(String date, String? userId) {
String? key = databaseRef.child("path").push().key;
databaseRef
.child("path")
.child(key!)
.set({'id': key, 'Ingrese nota': date});
}
}
As you can see in the image I can store them in a date and it shows me at the bottom
but when you leave and re-enter, what you entered is no longer there
What I want to do is listening to a stream which contains Lists of Events for each day of month.
I need this for my TableCalendar Widget
I want to count each Event of each list of the stream and display it in the calendar.
For this I wrote this function:
countEvents(DateTime datetime) {
eventBloc.getEventsOfDay(datetime).listen((event) {
counter = event.length;
});
}
This is where I execute the function (in markerBuilder):
StreamBuilder<List<Event>>(
stream: selectedEvents,
builder: (context, snapshot) {
if (snapshot.hasData) {
final events = snapshot.data;
groupEvents(allEventsList);
return Column(children: [
Card(
clipBehavior: Clip.antiAlias,
margin: const EdgeInsets.all(10),
elevation: 5,
child: TableCalendar(
firstDay: DateTime.utc(1970, 01, 01),
lastDay: DateTime.utc(2999, 12, 31),
focusedDay: _selectedDay,
locale: 'en_US',
onPageChanged: (focusedDay) {
_focusedDay = focusedDay;
},
selectedDayPredicate: (day) {
return isSameDay(_selectedDay, day);
},
headerStyle: HeaderStyle(
decoration: BoxDecoration(
color: AppColors.red,
),
headerMargin: const EdgeInsets.only(bottom: 10),
),
calendarStyle: CalendarStyle(),
calendarBuilders: CalendarBuilders(
markerBuilder: ((context, day, events) {
countEvents(day);
return Container(
width: 20,
height: 15,
decoration: BoxDecoration(
color: AppColors.red,
borderRadius: BorderRadius.circular(4.0)),
child: Text(counter.toString()),
);
})),
//Day Changed
onDaySelected: (DateTime selectDay, DateTime focusDay) {
setState(() {
_selectedDay = selectDay;
_focusedDay = focusDay;
selectedEvents =
eventBloc.getEventsOfDay(_selectedDay);
});
//print(_focusedDay);
},
startingDayOfWeek: StartingDayOfWeek.monday,
eventLoader: getEventsForDay,
),
counter is a global variable for the class
I used the debugger and it seems like the listen function is skipped all the time..
Thank you for your help!
Im trying to make changes in the existing code where in Firstpage it take the name of the trip and StartDate and Endate and other details. When the user click on upload image and comeback to main page I'm able to save the other field data in void savedata() but I'm stuck with how to store the data of startdate and enddate what the user has chosen before he going to second page. enter image description here - I have attached the screenshot how it looks when he choose the date and after coming back to firstpage from secondpage it shows like second picture. enter image description here my requirement here is how other field are storing the date I want startdate and enddate also store.
class _MyHomePageState extends State<DataInfoPage> {
_DataInfoPageState createState() => _DataInfoPageState();
String date = "";
final FirebaseAuth _auth = FirebaseAuth.instance;
User? user;
var name = '';
#override
void initState() {
super.initState();
initUser();
savedata();
}
initUser() async {
user = (_auth.currentUser!);
name = user!.displayName!;
setState(() {});
}
void savedata() {
final absavedata = context.read<AddTripBloc>();
if (absavedata.tripname != null) {
tripname.text = absavedata.tripname!;
//_selectedDateRange!.start = absavedata.sdate;
//_selectedDateRange!.end;
noofdays.text = absavedata.noofdays!;
noofnights.text = absavedata.noofnights!;
slotavail.text = absavedata.slotavail!;
priceperpers.text = absavedata.priceperpers!;
}
}
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
// DateTime selectedDate = DateTime.now();
//DateTime startDate = DateTime();
TextEditingController tripname = new TextEditingController();
TextEditingController noofdays = new TextEditingController();
TextEditingController noofnights = new TextEditingController();
TextEditingController slotavail = new TextEditingController();
TextEditingController priceperpers = new TextEditingController();
DateTimeRange? startdate;
DateTimeRange? enddate;
DateTimeRange? _selectedDateRange;
String _displayText(String begin, DateTime? date) {
if (date != null) {
return '$begin Date: ${date.toString().split(' ')[0]}';
} else {
return 'Press the button to show the picker';
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
SizedBox(
height: 20,
),
Text(
"Please enter trip details ",
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 25,
color: Colors.black),
),
SizedBox(
height: 20,
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 10, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
customfields(
hintValue: ' Enter Trip Name',
labeltxt: 'Trip Name *',
keyboardtype: TextInputType.text,
text: tripname),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
FloatingActionButton(
onPressed: _show,
child: const Icon(Icons.date_range_rounded),
shape: BeveledRectangleBorder(
borderRadius: BorderRadius.circular(5))),
Column(
children: [
Text(
_displayText(
'Start', _selectedDateRange?.start),
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
color: Colors.black),
),
SizedBox(
height: 20,
),
Text(
_displayText(
'End', _selectedDateRange?.end),
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
color: Colors.black))
],
),
SizedBox(
height: 20,
),
],
),
SizedBox(
height: 20,
),
customfields(
hintValue: ' No.of Days *',
labeltxt: 'No.of Days *',
keyboardtype: TextInputType.number,
text: noofdays),
SizedBox(
height: 20,
),
customfields(
hintValue: 'No.of Nights*',
labeltxt: 'No.of Nights*',
keyboardtype: TextInputType.number,
text: noofnights),
SizedBox(
height: 20,
),
customfields(
hintValue: 'Slots Available: *',
labeltxt: 'Slots Available: *',
keyboardtype: TextInputType.number,
text: slotavail,
),
SizedBox(
height: 20,
),
TextFormField(
style: TextStyle(
fontSize: 15, fontWeight: FontWeight.bold),
decoration: InputDecoration(
hintText: 'Price Per Person: *',
labelText: 'Price Per Person: *',
suffixIcon: Icon(
Icons.currency_rupee,
color: Colors.black,
size: 15,
),
),
controller: priceperpers,
keyboardType: TextInputType.number,
validator: (value) {
if (value!.isEmpty) {
return "This Field Can't be empty.";
}
return null;
},
),
// customfields(
// hintValue: 'Price Per Person: *',
// labeltxt: 'Price Per Person: *',
// keyboardtype: TextInputType.number,
// text: priceperpers,
// ),
//Text("Slots Available"),
SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () async {
final ab = context.read<AddTripBloc>();
ab.setpageonedata(
tripname.text,
_selectedDateRange!.start,
_selectedDateRange!.end,
noofdays.text,
noofnights.text,
slotavail.text,
priceperpers.text);
await Navigator.of(context).push(MaterialPageRoute(
builder: (context) => CameraWidget()));
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => CameraWidget()));
},
child: const Text("Upload Images of Trip *"),
),
SizedBox(
height: 35,
),
ElevatedButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
final ab = context.read<AddTripBloc>();
ab.setpageonedata(
tripname.text,
_selectedDateRange!.start,
_selectedDateRange!.end,
noofdays.text,
noofnights.text,
slotavail.text,
priceperpers.text);
//ab.savetripdata(user!);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PageTwo()));
}
setState(() {
_formKey.currentState?.save();
});
},
child: const Text("Save and Continue"),
)
],
)),
],
),
),
));
}
void _show() async {
final DateTimeRange? result = await showDateRangePicker(
context: context,
firstDate: DateTime(2022, 1, 1),
lastDate: DateTime(2030, 12, 31),
currentDate: DateTime.now(),
saveText: 'Done.',
);
if (result != null) {
// Rebuild the UI
String startdate = result.start.toString();
String enddate = result.end.toString();
// print(startdate);
//print(enddate);
//print(result.start.toString());
//print(result.end.toString());
setState(() {
startdate = result.start.toString();
enddate = result.end.toString();
_selectedDateRange = result;
});
}
}
}
I have the following calendar and code. How can I have the month be only 3 letters eg Nov 2021 instead of November 2021.
Container(
height: MediaQuery.of(context).size.height*0.3,
// width: MediaQuery.of(context).size.width*0.3,
color: Colors.white,
child: TableCalendar(
headerStyle: HeaderStyle(
titleTextStyle: TextStyle(fontSize: 12)
),
shouldFillViewport: true,
rowHeight:MediaQuery.of(context).size.height*0.02,
firstDay: DateTime.utc(2010, 10, 16),
lastDay: DateTime.utc(2030, 3, 14),
focusedDay: DateTime.now(),
onDaySelected: (selectedDay, focusedDay) {
if (!isSameDay(_selectedDay, selectedDay)) {
// Call `setState()` when updating the selected day
setState(() {
_selectedDay = selectedDay;
_focusedDay = focusedDay;
});
}
}
),
),
I achieved a responsive table with the customisation I wanted using this code:
Container(
height: MediaQuery.of(context).size.height*0.3,
color: Colors.white,
child: TableCalendar(
calendarStyle: CalendarStyle(
todayTextStyle: TextStyle(fontSize: MediaQuery.of(context).size.width*0.008,color: Colors.white),
weekendTextStyle: TextStyle(fontSize: MediaQuery.of(context).size.width*0.008),
outsideTextStyle: TextStyle(fontSize: MediaQuery.of(context).size.width*0.008),
defaultTextStyle: TextStyle(
fontSize: MediaQuery.of(context).size.width*0.008
)
) ,
headerStyle: HeaderStyle(
titleCentered: true,
titleTextFormatter: (date, locale) => DateFormat.yMMM(locale).format(date),
formatButtonVisible: false,
titleTextStyle: TextStyle(fontSize: MediaQuery.of(context).size.width*0.007)
),
shouldFillViewport: true,
rowHeight:MediaQuery.of(context).size.height*0.02,
firstDay: DateTime.utc(2010, 10, 16),
lastDay: DateTime.utc(2030, 3, 14),
focusedDay: DateTime.now(),
onDaySelected: (selectedDay, focusedDay) {
if (!isSameDay(_selectedDay, selectedDay)) {
// Call `setState()` when updating the selected day
setState(() {
_selectedDay = selectedDay;
_focusedDay = focusedDay;
});
}
}
),
),
as new table_calender 3.0.8 to disable two weeks/format button you can set
availableCalendarFormats: const {
CalendarFormat.month : 'Month'
}
and to center the title you also need to set up
headerStyle: HeaderStyle(
titleCentered: true
)
To remove 2 weeks use different calendarFormat
To change Header titile use titleTextFormatter
And finally play with PositionedOffset to control positions.
** Everything that is possible to change is documented here: https://pub.dev/documentation/table_calendar/latest/table_calendar/table_calendar-library.html
I've been facing errors regarding my Syncfusion Calendar. Just recently, I was not able to initialize my _startDate and _endDate variables but some people suggested to make it nullable which I did but now it is giving me "Null check operator used on a null value" error.
Calendar Code:
class EventCalendar extends StatefulWidget {
const EventCalendar({Key? key}) : super(key: key);
#override
EventCalendarState createState() => EventCalendarState();
}
List<Color> _colorCollection = <Color>[];
List<String> _colorNames = <String>[];
int _selectedColorIndex = 0;
late DataSource _events;
Meeting? _selectedAppointment;
DateTime? _startDate;
DateTime? _endDate;
late TimeOfDay _startTime;
late TimeOfDay _endTime;
bool _isAllDay = false;
String _subject = '';
String _notes = '';
class EventCalendarState extends State<EventCalendar> {
EventCalendarState(); //check
CalendarView _calendarView = CalendarView.month;
late List<String> eventNameCollection;
late List<Meeting> appointments;
#override
void initState() {
_calendarView = CalendarView.month;
appointments = getMeetingDetails();
_events = DataSource(appointments);
_selectedAppointment = null;
_selectedColorIndex = 0;
_subject = '';
_notes = '';
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: UserDrawer(),
appBar: AppBar(
iconTheme: IconThemeData(color: Colors.black),
backgroundColor: Colors.transparent,
elevation: 0,
centerTitle: true,
title: const Text('Itinerary',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
color: Colors.black)),
),
resizeToAvoidBottomInset: false,
body: Padding(
padding: const EdgeInsets.fromLTRB(5, 0, 5, 5),
child: getEventCalendar(_calendarView, _events)),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add, color: Colors.white),
backgroundColor: Color(0xFF003893),
onPressed: () => Navigator.push<Widget>(
context,
MaterialPageRoute(
builder: (BuildContext context) => EventEditor()),
)));
}
SfCalendar getEventCalendar(
CalendarView _calendarView,
CalendarDataSource _calendarDataSource,
) {
return SfCalendar(
view: _calendarView,
backgroundColor: Colors.transparent,
initialSelectedDate: DateTime.now(),
todayHighlightColor: Color(0xFF003893),
selectionDecoration: BoxDecoration(color: Colors.white60),
showNavigationArrow: true,
cellBorderColor: Colors.transparent,
firstDayOfWeek: 1,
allowedViews: [
CalendarView.day,
CalendarView.week,
CalendarView.month,
CalendarView.timelineWeek
],
monthViewSettings: MonthViewSettings(
showAgenda: true,
agendaViewHeight: 250,
appointmentDisplayMode: MonthAppointmentDisplayMode.appointment),
dataSource: _calendarDataSource,
initialDisplayDate: DateTime(DateTime.now().year, DateTime.now().month,
DateTime.now().day, 0, 0, 0),
timeSlotViewSettings: TimeSlotViewSettings(
minimumAppointmentDuration: const Duration(minutes: 60)),
);
}
void onCalendarViewChange(String value) {
if (value == 'Day') {
_calendarView = CalendarView.day;
} else if (value == 'Week') {
_calendarView = CalendarView.week;
} else if (value == 'Month') {
_calendarView = CalendarView.month;
} else if (value == 'Timeline week') {
_calendarView = CalendarView.timelineWeek;
}
setState(() {});
}
List<Meeting> getMeetingDetails() {
final List<Meeting> meetingCollection = <Meeting>[];
eventNameCollection = <String>[];
eventNameCollection.add('');
_colorCollection = <Color>[];
_colorCollection.add(const Color(0xFF3D4FB5));
_colorCollection.add(const Color(0xFF0F8644));
_colorCollection.add(const Color(0xFF8B1FA9));
_colorCollection.add(const Color(0xFFD20100));
_colorCollection.add(const Color(0xFFFC571D));
_colorCollection.add(const Color(0xFF85461E));
_colorCollection.add(const Color(0xFFFF00FF));
_colorCollection.add(const Color(0xFFE47C73));
_colorCollection.add(const Color(0xFF636363));
_colorNames = <String>[];
_colorNames.add('Blue');
_colorNames.add('Green');
_colorNames.add('Purple');
_colorNames.add('Red');
_colorNames.add('Orange');
_colorNames.add('Caramel');
_colorNames.add('Magenta');
_colorNames.add('Peach');
_colorNames.add('Gray');
return meetingCollection;
}
}
class DataSource extends CalendarDataSource {
DataSource(List<Meeting> source) {
appointments = source;
}
#override
bool isAllDay(int index) => appointments![index].isAllDay;
#override
String getSubject(int index) => appointments![index].eventName;
#override
String getNotes(int index) => appointments![index].description;
#override
Color getColor(int index) => appointments![index].background;
#override
DateTime getStartTime(int index) => appointments![index].from;
#override
DateTime getEndTime(int index) => appointments![index].to;
}
class Meeting {
Meeting(
{required this.from,
required this.to,
this.background = Colors.green,
this.isAllDay = false,
this.eventName = '',
this.description = ''});
final String eventName;
final DateTime from;
final DateTime to;
final Color background;
final bool isAllDay;
final String description;
}
Add/Edit/Delete Event in Calendar Code:
class EventEditorState extends State<EventEditor> {
Widget _getAppointmentEditor(BuildContext context) {
return Container(
color: Colors.white,
child: ListView(
padding: const EdgeInsets.all(12),
children: <Widget>[
ListTile(
contentPadding: const EdgeInsets.fromLTRB(10, 0, 0, 0),
title: TextFormField(
controller: TextEditingController(text: _subject),
onChanged: (String value) {
_subject = value;
},
keyboardType: TextInputType.multiline,
maxLines: null,
style: TextStyle(
fontSize: 15,
color: Colors.black,
fontWeight: FontWeight.w400),
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Title',
),
),
),
const Divider(
height: 1.0,
thickness: 1,
),
ListTile(
contentPadding: const EdgeInsets.all(5),
leading: Icon(
Icons.subject,
color: Colors.black87,
),
title: TextField(
controller: TextEditingController(text: _notes),
onChanged: (String value) {
_notes = value;
},
keyboardType: TextInputType.multiline,
maxLines: null,
style: TextStyle(
fontSize: 15,
color: Colors.black87,
fontWeight: FontWeight.w400),
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Add description',
),
),
),
const Divider(
height: 1.0,
thickness: 1,
),
ListTile(
contentPadding: const EdgeInsets.fromLTRB(10, 15, 20, 2),
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('From', style: TextStyle(fontWeight: FontWeight.w500)),
SizedBox(height: 5),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
flex: 7,
child: GestureDetector(
child: Text(
DateFormat('EEE, MMM dd yyyy')
.format(_startDate!),
textAlign: TextAlign.left),
onTap: () async {
final DateTime? date = await showDatePicker(
context: context,
initialDate: _startDate!,
firstDate: DateTime(1900),
lastDate: DateTime(2100),
);
if (date != null && date != _startDate) {
setState(() {
final Duration difference =
_endDate!.difference(_startDate!);
_startDate = DateTime(
date.year,
date.month,
date.day,
_startTime.hour,
_startTime.minute,
0);
_endDate = _startDate!.add(difference);
_endTime = TimeOfDay(
hour: _endDate!.hour,
minute: _endDate!.minute);
});
}
}),
),
Expanded(
flex: 3,
child: _isAllDay
? const Text('')
: GestureDetector(
child: Text(
DateFormat('hh:mm a')
.format(_startDate!),
textAlign: TextAlign.right,
),
onTap: () async {
final TimeOfDay? time =
await showTimePicker(
context: context,
initialTime: TimeOfDay(
hour: _startTime.hour,
minute: _startTime.minute));
if (time != null &&
time != _startTime) {
setState(() {
_startTime = time;
final Duration difference =
_endDate!
.difference(_startDate!);
_startDate = DateTime(
_startDate!.year,
_startDate!.month,
_startDate!.day,
_startTime.hour,
_startTime.minute,
0);
_endDate =
_startDate!.add(difference);
_endTime = TimeOfDay(
hour: _endDate!.hour,
minute: _endDate!.minute);
});
}
})),
]),
],
)),
ListTile(
contentPadding: const EdgeInsets.fromLTRB(10, 5, 20, 2),
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('To', style: TextStyle(fontWeight: FontWeight.w500)),
SizedBox(height: 5),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
flex: 7,
child: GestureDetector(
child: Text(
DateFormat('EEE, MMM dd yyyy')
.format(_endDate!),
textAlign: TextAlign.left,
),
onTap: () async {
final DateTime? date = await showDatePicker(
context: context,
initialDate: _endDate!,
firstDate: DateTime(1900),
lastDate: DateTime(2100),
);
if (date != null && date != _endDate) {
setState(() {
final Duration difference =
_endDate!.difference(_startDate!);
_endDate = DateTime(
date.year,
date.month,
date.day,
_endTime.hour,
_endTime.minute,
0);
if (_endDate!.isBefore(_startDate!)) {
_startDate =
_endDate!.subtract(difference);
_startTime = TimeOfDay(
hour: _startDate!.hour,
minute: _startDate!.minute);
}
});
}
}),
),
Expanded(
flex: 3,
child: _isAllDay
? const Text('')
: GestureDetector(
child: Text(
DateFormat('hh:mm a').format(_endDate!),
textAlign: TextAlign.right,
),
onTap: () async {
final TimeOfDay? time =
await showTimePicker(
context: context,
initialTime: TimeOfDay(
hour: _endTime.hour,
minute: _endTime.minute));
if (time != null && time != _endTime) {
setState(() {
_endTime = time;
final Duration difference =
_endDate!
.difference(_startDate!);
_endDate = DateTime(
_endDate!.year,
_endDate!.month,
_endDate!.day,
_endTime.hour,
_endTime.minute,
0);
if (_endDate!
.isBefore(_startDate!)) {
_startDate = _endDate!
.subtract(difference);
_startTime = TimeOfDay(
hour: _startDate!.hour,
minute: _startDate!.minute);
}
});
}
})),
]),
],
)),
SizedBox(height: 10),
ListTile(
contentPadding: const EdgeInsets.fromLTRB(10, 5, 20, 2),
leading: Icon(
Icons.access_time,
color: Colors.black54,
),
title: Row(children: <Widget>[
const Expanded(
child: Text('All-day'),
),
Expanded(
child: Align(
alignment: Alignment.centerRight,
child: Switch(
value: _isAllDay,
onChanged: (bool value) {
setState(() {
_isAllDay = value;
});
},
))),
])),
const Divider(
height: 1.0,
thickness: 1,
),
ListTile(
contentPadding: const EdgeInsets.fromLTRB(10, 5, 20, 2),
leading: Icon(Icons.lens,
color: _colorCollection[_selectedColorIndex]),
title: Text(
_colorNames[_selectedColorIndex],
),
onTap: () {
showDialog<Widget>(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return _ColorPicker();
},
).then((dynamic value) => setState(() {}));
},
),
const Divider(
height: 1.0,
thickness: 1,
),
],
));
}
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: Text(getTile()),
backgroundColor: _colorCollection[_selectedColorIndex],
leading: IconButton(
icon: const Icon(
Icons.close,
color: Colors.white,
),
onPressed: () {
Navigator.pop(context);
},
),
actions: <Widget>[
IconButton(
padding: const EdgeInsets.fromLTRB(5, 0, 5, 0),
icon: const Icon(
Icons.done,
color: Colors.white,
),
onPressed: () {
final List<Meeting> meetings = <Meeting>[];
if (_selectedAppointment != null) {
_events.appointments!.removeAt(_events.appointments!
.indexOf(_selectedAppointment));
_events.notifyListeners(CalendarDataSourceAction.remove,
<Meeting>[]..add(_selectedAppointment!));
}
meetings.add(Meeting(
from: _startDate!,
to: _endDate!,
background: _colorCollection[_selectedColorIndex],
description: _notes,
isAllDay: _isAllDay,
eventName: _subject == '' ? '(No Title)' : _subject,
));
_events.appointments!.add(meetings[0]);
_events.notifyListeners(
CalendarDataSourceAction.add, meetings);
_selectedAppointment = null;
Navigator.pop(context);
})
],
),
body: Padding(
padding: const EdgeInsets.fromLTRB(5, 5, 5, 5),
child: Stack(
children: <Widget>[_getAppointmentEditor(context)],
),
),
floatingActionButton: _selectedAppointment == null
? const Text('')
: FloatingActionButton(
onPressed: () {
if (_selectedAppointment != null) {
_events.appointments!.removeAt(_events.appointments!
.indexOf(_selectedAppointment));
_events.notifyListeners(CalendarDataSourceAction.remove,
<Meeting>[]..add(_selectedAppointment!));
_selectedAppointment = null;
Navigator.pop(context);
}
},
child:
const Icon(Icons.delete_outline, color: Colors.white),
backgroundColor: Colors.red,
)));
}
String getTile() {
return _subject.isEmpty ? 'New event' : 'Event details';
}
}
How do I solve this issue?