I encountered weird issue while creating a learning Todo App. I implemented TaskList Class and TaskTile class as below.
TaskList Class as below
import 'package:provider/provider.dart';
import 'package:todoey/Models/taskdata.dart';
import 'package:todoey/widgets/task_tile.dart';
class TasksList extends StatefulWidget {
@override
State<TasksList> createState() => _TasksListState();
}
class _TasksListState extends State<TasksList> {
@override
Widget build(BuildContext context) {
return Consumer<TaskData>(builder: (context, taskData, child) {
return ListView.builder(
itemBuilder: (context, index) {
final task = taskData.taskList[index];
return TaskTile(
longPressCallBack: () {
taskData.deleteTask(task);
},
name: task.name,
isChecked: task.isDone,
checkBoxCallBack: (newValue) {
taskData.updateTask(task);
},
);
},
itemCount: taskData.taskList.length,
);
});
}
}
TaskTile Class as below
class TaskTile extends StatelessWidget {
final bool? isChecked;
final String name;
final Function checkBoxCallBack;
final Function longPressCallBack;
TaskTile(
{required this.name,
this.isChecked,
required this.checkBoxCallBack,
required this.longPressCallBack});
@override
Widget build(BuildContext context) {
return ListTile(
title: Text(
name,
style: TextStyle(
decoration: isChecked! ? TextDecoration.lineThrough : null,
),
),
trailing: Checkbox(
fillColor: MaterialStateProperty.all(Colors.lightBlueAccent),
checkColor: Colors.white,
value: isChecked!,
onChanged: (newValue) {
checkBoxCallBack(newValue);
},
),
onLongPress: () => longPressCallBack,
);
}
}
Now the problem is it doesn't call longPressCallBack of parent class i.e. TaskList class. I debugged and it calls onLongPress of TaskTile class but not calling callback to it's parent class and that is why deleteTask not working.
CodePudding user response:
The problem is with this line onLongPress: () => longPressCallBack,
on your TaskTile
class. Here you are just invoking longPressCallBack
closure reference instead of executing the closure function.
Solution:
Change that line to this : onLongPress: () => longPressCallBack(),
or try directly passing function refrence to onLongPress
property of ListTile
like this onLongPress: longPressCallBack,
CodePudding user response:
You can use VoidCallback
instead, look at the following sample code:
class _MyWidgetState extends State<MyWidget> {
String greeting = "Hello World!";
@override
Widget build(BuildContext context) {
return Column(
children: [
Text(
greeting,
style: Theme.of(context).textTheme.headline4,
),
TestButton(
onClickCallback: () {
setState(() {
greeting = "Hello Test!";
});
}
),
],
);
}
}
class TestButton extends StatelessWidget {
final VoidCallback onClickCallback;
const TestButton( {required this.onClickCallback});
@override
Widget build(BuildContext context) {
return ElevatedButton(
child: const Text("TestButton"),
onPressed: onClickCallback,
);
}
}