3
respostas

Lista de task não atualiza

Olá,

O InheritedWidget não está atualizando a lista da tela inicial após adicionar uma nova tarefa. Notei que, ao criar uma nova tarefa e clicar no botão para aumentar o nível de outra tarefa já existente, a tela é atualizada, e a nova tarefa aparece.

  1. Chamada do form
floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.push(
            context,
            MaterialPageRoute(
              builder: (contextNew) => FormScreen(taskScreen: context)
            ),
          );
        },
  1. Confirmação da tarefa no form_screen
    ElevatedButton(
                        onPressed: () {
                          if (_formKey.currentState!.validate()) {
                            //debugPrint(nameController.text);
                            //debugPrint(difficultyController.text);
                            //debugPrint(imageController.text);

                            TaskInherited.of(widget.taskScreen).newTask(
                                nameController.text,
                                imageController.text,
                                int.parse(difficultyController.text));

                            ScaffoldMessenger.of(context).showSnackBar(
                              const SnackBar(
                                content: Text('Criando uma nova tarefa!'),
                              ),
                            );

                            Navigator.pop(context);
                          }
                        },
                        child: const Text('Adicionar'))
  1. TaskInherited
import 'package:flutter/material.dart';
import 'package:nosso_primeiro_projeto/components/task.dart';

class TaskInherited extends InheritedWidget {
  TaskInherited({
    super.key,
    required Widget child,
  }) : super(child: child);

  final List<Task> taskList = [
    Task(
        nome: 'Aprender Flutter',
        linkUrl: 'assets/images/Logo_Flutter.png',
        dificuldade: 2),
    Task(
        nome: 'Aprender React',
        linkUrl: 'assets/images/Logo_React_Native.png',
        dificuldade: 3),
    Task(
        nome: 'Aprender Kotlin',
        linkUrl: 'assets/images/Logo_Kotlin.png',
        dificuldade: 4),
  ];

  void newTask(String name, String photo, int difficulty) {
    taskList.add(Task(nome: name, linkUrl: photo, dificuldade: difficulty));
  }

  static TaskInherited of(BuildContext context) {
    final TaskInherited? result =
        context.dependOnInheritedWidgetOfExactType<TaskInherited>();
    assert(result != null, 'No TaskInherited found in context');
    return result!;
  }

  @override
  bool updateShouldNotify(TaskInherited oldWidget) {
    return oldWidget.taskList.length != taskList.length;
  }
}
3 respostas

Olá, Thiago.

Tudo bem?

Parece que você está lidando com um problema comum ao trabalhar com o Flutter e o InheritedWidget. A questão é que o InheritedWidget não está reconhecendo a atualização da lista após a adição de uma nova tarefa.

A razão para isso é que o InheritedWidget não está sendo reconstruído quando um novo item é adicionado à lista. Em Flutter, um widget só é reconstruído quando a referência do objeto muda. No seu caso, a referência da lista não está mudando, apenas o conteúdo dela.

Uma possível solução para isso seria criar um novo objeto de lista cada vez que você adicionar uma tarefa. Aqui está um exemplo de como você pode fazer isso:

void newTask(String name, String photo, int difficulty) {
  taskList = List.from(taskList)
    ..add(Task(nome: name, linkUrl: photo, dificuldade: difficulty));
}

Neste exemplo, List.from(taskList) cria um novo objeto de lista a partir da lista existente, e o operador ..add() é usado para adicionar a nova tarefa à nova lista. Como isso cria uma nova referência de objeto, o InheritedWidget deve reconhecer a mudança e se reconstruir.

Qualquer coisa manda aqui de novo. Valeu e bons estudos.

Olá Renan, boa tarde!

O código não funcionou. Fazendo essa alteração, ele parou de atualizar a tela em 100%.

import 'package:flutter/material.dart';
import 'package:nosso_primeiro_projeto/components/task.dart';

class TaskInherited extends InheritedWidget {
  TaskInherited({
    super.key,
    required Widget child,
  }) : super(child: child);

  List<Task> taskList = [
    Task(
        nome: 'Aprender Flutter',
        linkUrl: 'assets/images/Logo_Flutter.png',
        dificuldade: 2),
    Task(
        nome: 'Aprender React',
        linkUrl: 'assets/images/Logo_React_Native.png',
        dificuldade: 3),
    Task(
        nome: 'Aprender Kotlin',
        linkUrl: 'assets/images/Logo_Kotlin.png',
        dificuldade: 4),
  ];

  void newTask(String name, String photo, int difficulty) {
    taskList = List.from(taskList)
      ..add(Task(nome: name, linkUrl: photo, dificuldade: difficulty));
  }

  //void newTask(String name, String photo, int difficulty) {
  //  taskList.add(Task(nome: name, linkUrl: photo, dificuldade: difficulty));
  //}

  static TaskInherited of(BuildContext context) {
    final TaskInherited? result =
        context.dependOnInheritedWidgetOfExactType<TaskInherited>();
    assert(result != null, 'No TaskInherited found in context');
    return result!;
  }

  @override
  bool updateShouldNotify(TaskInherited oldWidget) {
    return oldWidget.taskList.length != taskList.length;
  }
}

Por que, no código feito pelo professor, esse problema não foi apresentado?

Tiago, eu estava com o mesmo problema, o que eu fiz pra resolver foi cirar um TaskInherited dentro da tela inicial antes do Scaffold para englobar todos os widgets e funcionou. Nao sei se é a solução correta mas funcionou. Kako poderia nos responder se isso é uma boa prática ?

Captura de tela do codigo que citei acima