'Flutter: I can't update Listview.builder

I want to add an item to my list the easiest way, but it doesn't change somehow. It must be simple, but somehow I cannot update my list. If the whole project is needed to solve this problem, I can share the GitHub link. This project is Angela Yu's flutter course last project on Udemy.

This is my add_task screen:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:todoey/model/task.dart';
import 'package:todoey/model/task_bank.dart';

class AddTaskScreen extends StatefulWidget {
  const AddTaskScreen({Key? key}) : super(key: key);
  static const data = "Add Task";
  static const data2 = "Add";

  @override
  State<AddTaskScreen> createState() => _AddTaskScreenState();
}

class _AddTaskScreenState extends State<AddTaskScreen> {
  TextEditingController textEditingController = TextEditingController();
  TaskBank taskBank = TaskBank();
  String newTaskText = "";
  void addItem() {
    setState(() {
      taskBank.allTasks.add(
        Task(
          text: newTaskText,
          isDone: false,
        ),
      );
      textEditingController.clear();
    });
    Navigator.pop(context);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: const Color(0xFF757575),
      child: Container(
        padding: const EdgeInsets.all(20),
        decoration: const BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.only(
              topLeft: Radius.circular(20), topRight: Radius.circular(20)),
        ),
        child: Column(
          children: [
            const Text(
              AddTaskScreen.data,
              style: TextStyle(
                color: Colors.lightBlueAccent,
                fontSize: 30.0,
              ),
            ),
            TextField(
              controller: textEditingController,
              autofocus: true,
              textAlign: TextAlign.center,
              onChanged: (newText) {
                newTaskText = newText;
              },
            ),
            const SizedBox(height: 10),
            CupertinoButton(
              child: const Text(AddTaskScreen.data2),
              onPressed: () {
                addItem();
              },
              color: Colors.lightBlueAccent,
            )
          ],
        ),
      ),
    );
  }
}

This is listview

import 'package:flutter/material.dart';
import 'package:todoey/model/task_bank.dart';

class TasksListView extends StatefulWidget {
  const TasksListView({
    Key? key,
  }) : super(key: key);

  @override
  State<TasksListView> createState() => _TasksListViewState();
}

class _TasksListViewState extends State<TasksListView> {
  TaskBank taskBank = TaskBank();

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 20.0),
      decoration: const BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.only(
          topLeft: Radius.circular(20),
          topRight: Radius.circular(20),
        ),
      ),
      child: ListView.builder(
        itemCount: taskBank.allTasks.length,
        itemBuilder: (context, index) {
          bool isChecked = taskBank.allTasks[index].isDone;
          return ListTile(
            title: Text(taskBank.allTasks[index].text),
            trailing: Checkbox(
              checkColor: Colors.lightBlueAccent,
              value: isChecked,
              onChanged: (newVlue) {
                setState(() {
                  isChecked
                      ? isChecked = taskBank.taskDidntDone(index)
                      : isChecked = taskBank.taskDone(index);
                });
                print(taskBank.allTasks.length);
              },
            ),
          );
        },
      ),
    );
  }
}

And these are my models.

 class Task {
  String text;
  bool isDone;
  Task({required this.text, this.isDone = false});
}

    import 'package:todoey/model/task.dart';

class TaskBank {
  List<Task> allTasks = [
    Task(
      text: "Complete to Listview Challange",
      isDone: false,
    ),
    Task(
      text: "Complate to Udemy Course",
      isDone: false,
    ),
  ];

  bool taskDone(int index) {
    return allTasks[index].isDone = true;
  }

  bool taskDidntDone(int index) {
    return allTasks[index].isDone = false;
  }
}


Solution 1:[1]

The issue is here TasksListView is on separate context and Ui is not getting updated. A simple solution will be passing TaskBank on TasksListView. I will encourage you to look on state-management.

Run on dartPad

class TasksListView extends StatefulWidget {
  final TaskBank taskBank;
  const TasksListView({
    Key? key,
    required this.taskBank,
  }) : super(key: key);

  @override
  State<TasksListView> createState() => _TasksListViewState();
}

class _TasksListViewState extends State<TasksListView> {
  late TaskBank taskBank;
  @override
  void initState() {
    super.initState();
    taskBank = widget.taskBank;
  }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Yeasin Sheikh