I am new learner in flutter, I try to read the existing data from Firebase Firestore so that I can get back the data and perform update function in the page, but I encounter error when I click the button that redirect me to the update page is blank and given such Exception that I stated at below. Can anyone help me to identify which part is triggering this issues. Appreciate those help, thank you.
Exception:
═══════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown while looking for parent data.:
Incorrect use of ParentDataWidget.
The following ParentDataWidgets are providing parent data to the same RenderObject:
- Expanded(flex: 1) (typically placed directly inside a Flex widget)
- LayoutId-[<_ScaffoldSlot.body>](id: _ScaffoldSlot.body) (typically placed directly inside a CustomMultiChildLayout widget)
However, a RenderObject can only receive parent data from at most one ParentDataWidget.
Usually, this indicates that at least one of the offending ParentDataWidgets listed above is not placed directly inside a compatible ancestor widget.
The ownership chain for the RenderObject that received the parent data was:
RepaintBoundary ← NotificationListener<ScrollNotification> ← GlowingOverscrollIndicator ← Scrollable ← PrimaryScrollController ← ListView ← Expanded ← GetBuilder<TaskController> ← KeyedSubtree-[GlobalKey#0d8bd] ← _BodyBuilder ← ⋯
When the exception was thrown, this was the stack
#0 RenderObjectElement._findAncestorParentDataElement.<anonymous closure>
framework.dart:5792
#1 RenderObjectElement._findAncestorParentDataElement
framework.dart:5806
#2 RenderObjectElement.attachRenderObject
framework.dart:6157
#3 RenderObjectElement.mount
framework.dart:5828
#4 SingleChildRenderObjectElement.mount
framework.dart:6376
... Normal element mounting (73 frames)
#77 Element.inflateWidget
framework.dart:3953
#78 MultiChildRenderObjectElement.inflateWidget
framework.dart:6512
#79 MultiChildRenderObjectElement.mount
framework.dart:6524
... Normal element mounting (318 frames)
#397 Element.inflateWidget
framework.dart:3953
#398 MultiChildRenderObjectElement.inflateWidget
framework.dart:6512
#399 MultiChildRenderObjectElement.mount
framework.dart:6524
... Normal element mounting (682 frames)
#1081 Element.inflateWidget
framework.dart:3953
#1082 MultiChildRenderObjectElement.inflateWidget
framework.dart:6512
#1083 Element.updateChild
framework.dart:3682
#1084 RenderObjectElement.updateChildren
framework.dart:6041
#1085 MultiChildRenderObjectElement.update
framework.dart:6537
#1086 Element.updateChild
framework.dart:3660
#1087 ComponentElement.performRebuild
framework.dart:4993
#1088 StatefulElement.performRebuild
framework.dart:5133
#1089 Element.rebuild
framework.dart:4690
#1090 StatefulElement.update
framework.dart:5156
#1091 Element.updateChild
framework.dart:3660
#1092 ComponentElement.performRebuild
framework.dart:4993
#1093 Element.rebuild
framework.dart:4690
#1094 ProxyElement.update
framework.dart:5301
#1095 Element.updateChild
framework.dart:3660
#1096 ComponentElement.performRebuild
framework.dart:4993
#1097 Element.rebuild
framework.dart:4690
#1098 ProxyElement.update
framework.dart:5301
#1099 _InheritedNotifierElement.update
inherited_notifier.dart:107
#1100 Element.updateChild
framework.dart:3660
#1101 ComponentElement.performRebuild
framework.dart:4993
#1102 StatefulElement.performRebuild
framework.dart:5133
#1103 Element.rebuild
framework.dart:4690
#1104 StatefulElement.update
framework.dart:5156
#1105 Element.updateChild
framework.dart:3660
#1106 ComponentElement.performRebuild
framework.dart:4993
#1107 Element.rebuild
framework.dart:4690
#1109 _InheritedNotifierElement.update
inherited_notifier.dart:107
#1110 Element.updateChild
framework.dart:3660
#1111 ComponentElement.performRebuild
framework.dart:4993
#1112 StatefulElement.performRebuild
framework.dart:5133
#1113 Element.rebuild
framework.dart:4690
#1114 StatefulElement.update
framework.dart:5156
#1115 Element.updateChild
framework.dart:3660
#1116 ComponentElement.performRebuild
framework.dart:4993
#1117 Element.rebuild
framework.dart:4690
#1118 ProxyElement.update
framework.dart:5301
#1119 Element.updateChild
framework.dart:3660
#1120 ComponentElement.performRebuild
framework.dart:4993
#1121 StatefulElement.performRebuild
framework.dart:5133
#1122 Element.rebuild
framework.dart:4690
#1123 StatefulElement.update
framework.dart:5156
#1124 Element.updateChild
framework.dart:3660
#1125 SingleChildRenderObjectElement.update
framework.dart:6384
#1126 Element.updateChild
framework.dart:3660
#1127 SingleChildRenderObjectElement.update
framework.dart:6384
#1128 Element.updateChild
framework.dart:3660
#1129 ComponentElement.performRebuild
framework.dart:4993
#1130 Element.rebuild
framework.dart:4690
#1131 ProxyElement.update
framework.dart:5301
#1132 Element.updateChild
framework.dart:3660
#1133 ComponentElement.performRebuild
framework.dart:4993
#1134 StatefulElement.performRebuild
framework.dart:5133
#1135 Element.rebuild
framework.dart:4690
#1136 BuildOwner.buildScope
framework.dart:2743
#1137 WidgetsBinding.drawFrame
binding.dart:863
#1138 RendererBinding._handlePersistentFrameCallback
binding.dart:381
#1139 SchedulerBinding._invokeFrameCallback
binding.dart:1289
#1140 SchedulerBinding.handleDrawFrame
binding.dart:1218
#1141 SchedulerBinding._handleDrawFrame
binding.dart:1076
#1142 _invoke (dart:ui/hooks.dart:145:13)
#1143 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:338:5)
#1144 _drawFrame (dart:ui/hooks.dart:112:31)
════════════════════════════════════════════════════════════════════════════════
Page that encounter this error:
// ignore_for_file: avoid_unnecessary_containers, avoid_print, unused_import, no_leading_underscores_for_local_identifiers, unused_label
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:fyp_version1/controllers/auth_controller.dart';
import 'package:fyp_version1/controllers/firebase_controller.dart';
import 'package:fyp_version1/controllers/task_controller.dart';
import 'package:fyp_version1/light_dark_themes/theme.dart';
import 'package:fyp_version1/models/task.dart';
import 'package:fyp_version1/widgets/button.dart';
import 'package:fyp_version1/widgets/input_field.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
class UpdatingTaskPage extends StatefulWidget {
final String id, title, note, date, startTime, endTime, repeat;
final int color, remind;
final bool isCompleted;
const UpdatingTaskPage(
{super.key,
required this.id,
required this.title,
required this.note,
required this.date,
required this.startTime,
required this.endTime,
required this.repeat,
required this.color,
required this.remind,
required this.isCompleted});
@override
State<UpdatingTaskPage> createState() => _UpdatingTaskPageState();
}
class _UpdatingTaskPageState extends State<UpdatingTaskPage> {
static TaskController controller = Get.put(TaskController());
final task = controller.tasks.length;
TextEditingController titleController = TextEditingController();
TextEditingController noteController = TextEditingController();
late DateTime _selecteDate = DateTime.now();
late String _startTime =
DateFormat('hh:mm a').format(DateTime.now()).toString();
String _endTime = DateFormat('hh:mm a')
.format(DateTime.now().add(const Duration(minutes: 60)))
.toString();
int _selectedRemind = 5;
List<int> remindList = [5, 10, 15, 20];
String _selectedRepeat = 'None';
List<String> repeatList = ['None', 'Daily', 'Weekly', 'Monthly'];
int _selectedColor = 0;
List<Color> colorList = [
bluishClr,
yellowClr,
redClr,
greenClr,
];
@override
Widget build(BuildContext context) {
titleController.text = widget.title;
noteController.text = widget.note;
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text("Update task!"),
centerTitle: true,
actions: [
IconButton(
onPressed: () {
// this icon button is for the user to signout
AuthController.instance.logout();
},
icon: const Icon(Icons.logout_rounded))
],
),
body: GetBuilder<TaskController>(
init: Get.put<TaskController>(TaskController()),
builder: (controller) {
return Expanded(
child: ListView.builder(
itemCount: controller.tasks.length,
itemBuilder: (BuildContext context, int index) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: SingleChildScrollView(
child: Column(
children: [
//Title
InputField(
title: 'Title',
hint: 'Enter your title here...',
controller: titleController,
),
//Note
InputField(
title: 'Note',
hint: 'Enter your note here...',
controller: noteController,
),
//Date
InputField(
title: 'Date',
hint: DateFormat.yMd().format(_selecteDate),
child: IconButton(
onPressed: () => _getDateFromUser(),
icon: const Icon(
Icons.calendar_today_outlined,
color: Colors.grey,
),
),
),
//Date Range
Row(
children: [
Expanded(
child: InputField(
title: 'Start Time',
hint: _startTime,
child: IconButton(
onPressed: () =>
_getTimeFromUser(isStartTime: true),
icon: const Icon(
Icons.access_time_rounded,
color: Colors.grey,
),
),
),
),
Expanded(
child: InputField(
title: 'End Time',
hint: _endTime,
child: IconButton(
onPressed: () => _getTimeFromUser(
isStartTime: false),
icon: const Icon(
Icons.access_time_rounded,
color: Colors.grey,
),
),
),
),
],
),
//Remind
InputField(
title: 'Date',
hint: '$_selectedRemind minutes early',
child: DropdownButton(
onChanged: (String? newVal) {
setState(() {
_selectedRemind = int.parse(newVal!);
});
},
items: remindList
.map<DropdownMenuItem<String>>(
(e) => DropdownMenuItem<String>(
value: e.toString(),
child: Text('$e minutes'),
),
)
.toList(),
icon: const Icon(
Icons.keyboard_arrow_down,
size: 32,
color: Colors.grey,
),
elevation: 3,
underline: Container(height: 0),
borderRadius: BorderRadius.circular(15),
),
),
//Repeat
InputField(
title: 'Repeat',
hint: _selectedRepeat,
child: DropdownButton<String>(
onChanged: (String? value) {
setState(() {
_selectedRepeat = value!;
});
},
value: widget.repeat,
items: repeatList
.map<DropdownMenuItem<String>>(
(e) => DropdownMenuItem<String>(
value: e,
child: Text(e),
),
)
.toList(),
icon: const Icon(
Icons.keyboard_arrow_down,
size: 32,
color: Colors.grey,
),
elevation: 3,
underline: Container(height: 0),
borderRadius: BorderRadius.circular(15),
),
),
//Color
Container(
margin: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 10.0),
alignment: Alignment.centerLeft,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Color'),
Row(
children: List.generate(
colorList.length,
(index) => Padding(
padding: const EdgeInsets.only(
right: 5.0, top: 8),
child: InkWell(
onTap: () {
setState(() {
Value(widget.color);
_selectedColor = index;
});
},
borderRadius:
BorderRadius.circular(50),
child: CircleAvatar(
backgroundColor: colorList[index],
child: index == _selectedColor
? const Icon(
Icons.check,
color: Colors.white,
)
: null,
),
),
),
),
)
],
),
),
],
),
),
); // edited
} // edited
),
); // edited
} // edited
),
floatingActionButton: MyButton(
label: 'Save',
onTap: () {
// final title = titleController.text;
// final note = noteController.text;
_validateData();
}),
),
);
}
_validateData() async {
if (titleController.text.isNotEmpty && noteController.text.isNotEmpty) {
print(1);
_updateTaskToDb();
Get.back();
} else if (titleController.text.isEmpty || noteController.text.isEmpty) {
print(2);
Get.snackbar(
'Required',
'All fileds are required',
backgroundColor: Colors.white,
snackPosition: SnackPosition.BOTTOM,
colorText: Colors.black,
icon: const Icon(
Icons.warning_amber_rounded,
color: Colors.red,
),
);
} else {
print('######## Error Here ! ########');
}
}
_updateTaskToDb() async {
await FirestoreDB.updateTask(
taskModel: Task(
id: FirebaseAuth.instance.currentUser!.uid,
title: titleController.text,
note: noteController.text,
isCompleted: false,
date: DateFormat.yMd().format(_selecteDate),
startTime: _startTime,
endTime: _endTime,
color: _selectedColor,
remind: _selectedRemind,
repeat: _selectedRepeat,
),
);
}
_getDateFromUser() async {
DateTime? _pickedDate = await showDatePicker(
context: context,
initialDate: _selecteDate,
firstDate: DateTime(2020),
lastDate: DateTime(2030),
);
if (_pickedDate != null) {
setState(() {
Value(widget.date);
_selecteDate = _pickedDate;
});
} else {
print('picked date empty !');
}
}
_getTimeFromUser({required bool isStartTime}) async {
TimeOfDay? _pickedTime = await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
);
if (_pickedTime != null) {
setState(() {
if (isStartTime) {
_startTime = _pickedTime.format(context);
print(_startTime);
} else {
_endTime = _pickedTime.format(context);
print(_endTime);
}
});
}
}
}
3
Answers
remove the Expanded from the Listview builder
Try this :
Expanded
can only be used as a direct child of aFlex
widget likeColumn
orRow
. In this part of the codeit’s not. So remove the
Expanded
there and directly return theListView