I'm writing a taskList class that should allow me to check tasks as done. Everything works except for the Checkbox itself. I cannot get the screen to update the checkBox to actually check. onChanged part of each checkbox is where I should be able to update not only the screen but also the boolean isCompleted of each task with setState. Unfortunately, the only way I have been able to get onChanged to work, ie. check the box, is by declaring variables in the class itself and using those instead.
For this reason I believe that the issue has to do with me using a variable within an object. I think that flutter doesn't recognize that when userTaskList[index].isComplete is changed it will affect the screen so it doesn't bother rebuilding. I'm new to flutter so this could be totally wrong. ** I click on the checkbox, it changes variables, it does not update the screen with a check mark in the box.**
Here is the where the problem is in my TaskList Widget
import 'package:flutter/material.dart';
import '../models/task.dart';
import 'package:intl/intl.dart';
class TaskList extends StatefulWidget {
const TaskList({super.key});
@override
State<TaskList> createState() => _TaskListState();
}
class _TaskListState extends State<TaskList> {
@override
Widget build(BuildContext context) {
List<Task> userTaskList = [
Task(name: "Spanish Hw", dueDate: DateTime.now(), priority: 1),
Task(name: "Push Day", dueDate: DateTime.now(), priority: 3),
Task(name: "English HL Essay", dueDate: DateTime.now(), priority: 2)
];
return Container(
height: 300,
margin: const EdgeInsets.all(20),
child: ListView.builder(
itemCount: userTaskList.length,
itemBuilder: ((context, index) {
return Dismissible(
key: ValueKey(userTaskList[index]),
onDismissed: (direction) {
userTaskList.removeAt(index);
},
direction: DismissDirection.startToEnd,
background: Container(
padding: const EdgeInsets.all(10),
alignment: Alignment.centerLeft,
color: Colors.red,
child: const Icon(
Icons.delete,
color: Colors.white,
)),
child: Card(
elevation: 10,
child: SizedBox(
height: 50,
**child: CheckboxListTile(
//subtitle: Text(taskList[index].description),
activeColor: Colors.green,
value: userTaskList[index].isComplete,
onChanged: (val) {
print('Checkbox clicked, new value: $val');
setState(() {
userTaskList[index].isComplete = val ?? false;
});
},**
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
userTaskList[index].name,
textAlign: TextAlign.center,
),
Text(
DateFormat('EEEE, MMM D')
.format(userTaskList[index].dueDate),
textAlign: TextAlign.right,
),
],
),
),
),
));
}),
),
);
}
}
And Just incase it is important here is my Task class
import 'package:flutter/material.dart';
class Task {
bool isComplete = false;
String name;
String? description = "";
DateTime dueDate;
//If you have time use RatingBar() for priority
int priority;
Task(
{required this.name,
this.description,
required this.dueDate,
required this.priority});
}
CodePudding user response:
- The variable must be defined outside the body of the build method, otherwise it will be initialized when SetState.
class _TaskListState extends State<TaskList> {
List<Task> userTaskList = [
Task(name: "Spanish Hw", dueDate: DateTime.now(), priority: 1),
Task(name: "Push Day", dueDate: DateTime.now(), priority: 3),
Task(name: "English HL Essay", dueDate: DateTime.now(), priority: 2)
];
@override
Widget build(BuildContext context) {