I am using the table_calendar
package.
I want to display events for a current date below the calendar.
Below the events I have a textfield
to create a new event. Whenever I try to create a new event the textfield
doesn't show as it gets overflowed by the calendar.
I have tried using SingleChildScrollView
, changing my Expanded
to Container
and I've set resizeToAvoidBottomInset: false
.
Below is my code and an example screenshot of my UI
@override
Widget build(BuildContext context){
return Scaffold(
resizeToAvoidBottomInset: false,
body: Column(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(10, 20, 10,10),
child: Container(
//height: 400,
color: Colors.black,
child: TableCalendar(
rowHeight: 50,
firstDay: FirstDay,
lastDay: LastDay,
focusedDay: _focusedDay,
selectedDayPredicate: (day){
return isSameDay(_selectedDay, day);
},
onDaySelected: (selectedDay, focusedDay){
setState(() {
_selectedDay = selectedDay;
_focusedDay = focusedDay;
});
},
calendarFormat: _calendarFormat,
onFormatChanged: (format){
setState(() {
_calendarFormat = format;
});
},
eventLoader: _getEventsForDay,
startingDayOfWeek: StartingDayOfWeek.monday,
calendarStyle: CalendarStyle(
outsideDaysVisible: false,
),
onRangeSelected: _onRangeSelected,
onPageChanged: (focusedDay) {
_focusedDay = focusedDay;
},
),
),
),
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: 2.0,
),
decoration: BoxDecoration(
border: Border.all(),
borderRadius: BorderRadius.circular(12.0),
color: Colors.black,
),
child: ListTile(
onTap: () => print('${value[index]}'),
title: Text('${value[index]}'),
trailing: Wrap(
children: [
IconButton(icon: Icon(Icons.edit), onPressed: () => onPressEdit()),
IconButton(icon: Icon(Icons.delete, color: Colors.red), onPressed: () => onPressDelete()),
],
),
),
);
},
);
},
),
),
Container(
height:50,
child: Padding(
padding: const EdgeInsets.all(5),
child: Row(
children: [
Expanded(
child: TextField(
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left:15),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
),
hintText: 'Add event on ${formatter.format(_focusedDay)}',
),
),
),
Padding(
padding: const EdgeInsets.only(left:10),
child: FloatingActionButton(
onPressed: () {
selectedEvents[_selectedDay]?.add(Event2(title: "Test title"));
print("test");
setState((){});
print(selectedEvents);
return;
},
backgroundColor: Colors.black,
child:
const Text(' ',
style: TextStyle(color: Colors.white,
fontSize: 30,
),
),
),
),
],
),
),
),
]),
);
}
Thanks in advance
CodePudding user response:
If your ListView's Item are not too long you can use SingleChildScrollView
and set ListView's shrinkWrap
to true
, don't forget to remove Expanded
widget, try this:
SingleChildScrollView(//<-- add this
child: Column(children: [
Padding(
padding: const EdgeInsets.fromLTRB(10, 20, 10, 10),
child: Container(
//height: 400,
color: Colors.black,
child: TableCalendar(
rowHeight: 50,
firstDay: FirstDay,
lastDay: LastDay,
focusedDay: _focusedDay,
selectedDayPredicate: (day) {
return isSameDay(_selectedDay, day);
},
onDaySelected: (selectedDay, focusedDay) {
setState(() {
_selectedDay = selectedDay;
_focusedDay = focusedDay;
});
},
calendarFormat: _calendarFormat,
onFormatChanged: (format) {
setState(() {
_calendarFormat = format;
});
},
eventLoader: _getEventsForDay,
startingDayOfWeek: StartingDayOfWeek.monday,
calendarStyle: CalendarStyle(
outsideDaysVisible: false,
),
onRangeSelected: _onRangeSelected,
onPageChanged: (focusedDay) {
_focusedDay = focusedDay;
},
),
),
),
ValueListenableBuilder<List<Event>>(//<--- change this
valueListenable: _selectedEvents,
builder: (context, value, _) {
return ListView.builder(
shrinkWrap: true, //<-- add this
itemCount: value.length,
itemBuilder: (context, index) {
return Container(
margin: const EdgeInsets.symmetric(
horizontal: 12.0,
vertical: 2.0,
),
decoration: BoxDecoration(
border: Border.all(),
borderRadius: BorderRadius.circular(12.0),
color: Colors.black,
),
child: ListTile(
onTap: () => print('${value[index]}'),
title: Text('${value[index]}'),
trailing: Wrap(
children: [
IconButton(
icon: Icon(Icons.edit),
onPressed: () => onPressEdit()),
IconButton(
icon: Icon(Icons.delete, color: Colors.red),
onPressed: () => onPressDelete()),
],
),
),
);
},
);
},
),
Container(
height: 50,
child: Padding(
padding: const EdgeInsets.all(5),
child: Row(
children: [
Expanded(
child: TextField(
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 15),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
),
hintText:
'Add event on ${formatter.format(_focusedDay)}',
),
),
),
Padding(
padding: const EdgeInsets.only(left: 10),
child: FloatingActionButton(
onPressed: () {
selectedEvents[_selectedDay]
?.add(Event2(title: "Test title"));
print("test");
setState(() {});
print(selectedEvents);
return;
},
backgroundColor: Colors.black,
child: const Text(
' ',
style: TextStyle(
color: Colors.white,
fontSize: 30,
),
),
),
),
],
),
),
),
]),
)
CodePudding user response:
You could wrap the whole TableCalendar in a ListView with shrinkWarp = true and then the ListView into a Expanded. This way the Calendar will have enough space inside the ListView while the Keyboard is opened but is still fitted inside the Column.
Expanded(
child: ListView(
shrinkWrap: true,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(10, 20, 10, 10),
child: Container(
// height: 400,
color: Colors.black,
child: TableCalendar(),
),
),
],
),
),