-1

I am trying to do a todoapp with Provider but it is not working as expected. In my HomeScreen, I have a list of tasks, which is being stored in the provider. To edit a task, I go to another screen, TaskScreen, where I submit a form and, ideally, it should update the list, but it does not. Actually it does, but only after a hot reload, it is not synchronized.

class Task extends StatelessWidget {
  String title;

  Task({super.key, required this.title});

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => {
        Navigator.of(context).pushNamed(
          '/task',
          arguments: TitleTask(title: title),
        ),
        FocusManager.instance.primaryFocus?.unfocus(),
      },
      child: Dismissible(
        key: Key(title),
        child: Container(
          decoration: BoxDecoration(
            border: Border.all(
              color: Colors.blue,
              width: 1,
              style: BorderStyle.solid,
            ),
            borderRadius: BorderRadius.circular(10),
            color: Colors.grey[300],
          ),
          margin: const EdgeInsets.only(bottom: 8.0),
          child: ListTile(
            title: Text(
              title,
              style: const TextStyle(fontSize: 18),
            ),
            trailing: Wrap(
              spacing: 0,
              children: <IconButton>[
                IconButton(
                  padding: EdgeInsets.zero,
                  icon: const Icon(Icons.delete),
                  color: Colors.red,
                  onPressed: () => context.read<Tasks>().delete(title),
                ),
                IconButton(
                  padding: EdgeInsets.zero,
                  icon: const Icon(Icons.check),
                  color: Colors.green,
                  onPressed: () => {},
                )
              ],
            ),
          ),
        ),
        onDismissed: (direction) => context.read<Tasks>().delete(title),
      ),
    );
  }
}

class Tasks with ChangeNotifier {
  final List<Task> _tasks = [];

  List get tasks => _tasks;

  void add(String title) {
    _tasks.add(Task(title: title));
    notifyListeners();
  }

  void delete(String title) {
    _tasks.removeWhere((element) => element.title == title);
    notifyListeners();
  }

  void edit(String? taskTitle, String newTaskTitle) {
    _tasks[_tasks.indexWhere((element) => element.title == taskTitle)].title =
        newTaskTitle;
    notifyListeners();
  }
}

I am building the list of tasks like this:

ListView.builder(
                    scrollDirection: Axis.vertical,
                    shrinkWrap: true,
                    itemCount: context.watch<Tasks>().tasks.length,
                    itemBuilder: (context, index) {
                      final item = context.watch<Tasks>().tasks[index];

                      return item;
                    },

Does anyone know what is happening? I fear it may be related to the provider not knowing that it needs to update, because it knows the value and it doesn't update.

bringand1
  • 103
  • 1
  • 8

1 Answers1

0

To achieve exactly what you want you need to wrap your ListView with Consumer class instead of using watch inside of ListView.builder

    Consumer<Tasks>(
          builder: (_, data, __) => ListView.builder(
                    scrollDirection: Axis.vertical,
                    shrinkWrap: true,
                    itemCount: data.tasks.length,
                    itemBuilder: (context, index) {
                      final item = data.tasks[index];
    
                      return item;
                    },)
    )

Happy coding

powerman23rus
  • 1,297
  • 1
  • 9
  • 17
  • Thanks for replying. I resolved the issue without using the Consumer class. The problem was with these lines: ``` final item = data.tasks[index]; return item; ``` I just changed to: final Task task = tasks[index]; return TaskWidget(task: task); ``` and it worked. I don't know if is wasn't reconstructing the ListTiles without specifying that each of them were a instance of Task, but it worked. I refactored a little bit, so the names are a bit different, but I get now what I did wrong. Even so, is that right? – bringand1 Oct 25 '22 at 01:28
  • Sorry I don't follow you. Task already is widget I can't find any TaskWidget in your code? – powerman23rus Oct 25 '22 at 04:05
  • I am sorry. I refactored my code a bit and changed some things and added some. The TaskWidget you see in my comment was one of the changes. Anyway, I did solve my problem. Thank you regardless. – bringand1 Oct 26 '22 at 00:45