4
respostas

[Dúvida] Atualização da lista após adicionar

Se a lista iniciar vazia ou com poucas tarefas adicionadas a atualização da tela inicial não ocorre após adicionar uma nova/primeira tarefa. Acredito que ela só atualiza quando há uma certa quantidade de tarefas pois assim é possível rolar a tela (ListView) e forçar assim um rebuild da tela, carregando a lista de Task atualizada. Como resolver isso? Como fazer para a tela inicial rebuildar mesmo que a Task adicionada seja a primeira da lista? Como rebuildar a tela sem ter que rolar o ListView para forçar o rebuild?

4 respostas

Olá, Nicolas, como vai?

Quando você adiciona uma nova tarefa, o setState precisa ser chamado para que o Flutter saiba que precisa rebuildar a tela, mesmo que a lista tenha apenas um item.

Você pode transformar a lista de tasks em uma lista dinâmica e usar o setState para atualizar a interface. Na InitialScreen, precisamos esperar o retorno da nova tarefa ao navegar para a tela de formulário e, quando recebê-la, adicionar à lista de tarefas e atualizar a tela.

Vou deixar aqui o código e um gif demonstrando o resultado:

demonstrando a renderização dinamica da lista de tarefas do projeto

O código do arquivo initial_screen.dart ficou da seguinte forma:

import 'package:flutter/material.dart';
import 'package:flutter_aula_2/components/task.dart';
import 'package:flutter_aula_2/screens/form_screen.dart';

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

  @override
  State<InitialScreen> createState() => _InitialScreenState();
}

class _InitialScreenState extends State<InitialScreen> {
  // Lista dinâmica de tarefas
  List<Task> tasks = [
    //Task('Aprender Flutter', 'assets/images/dash.png', 3),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: Container(),
        title: const Text('Tarefas'),
      ),
      body: ListView.builder(
        itemCount: tasks.length,
        itemBuilder: (context, index) {
          return tasks[index];
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          // Navegar para FormScreen e esperar o retorno da nova tarefa
          final newTask = await Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) => FormScreen(),
            ),
          );

          // Se receber uma nova tarefa, adicioná-la à lista e atualizar a tela
          if (newTask != null && newTask is Task) {
            setState(() {
              tasks.add(newTask);
            });
          }
        },
        child: const Icon(Icons.add),
      ),
    );
  }
}

Caso precise ajustar o botão para o envio do fomulário, o meu ficou da seguinte forma:

   ElevatedButton(
                    onPressed: () {
                      if (_formKey.currentState!.validate()) {
                        // Criação da nova tarefa
                        Task newTask = Task(
                          nameController.text,
                          imageController.text,
                          int.parse(difficultyController.text),
                        );

                        // Retornar a nova tarefa e fechar a tela
                        Navigator.pop(context, newTask);
                      }
                    },
                    child: Text('Adicionar!'),
                  ),

Espero ter ajudado!

Siga firme nos seus estudos e conte com o fórum sempre que precisar!

Abraços :)

Caso este post tenha lhe ajudado, por favor, marcar como solucionado

Solução perfeita. Mas onde foi utilizado o InhiretedWidget? Porque, pelo que eu entendi no curso, a ideia de usar o InhiretedWidget era justamente pra não usar o setState já que updateShouldNotify atualizaria a variável caso houvesse a mudança estabelecida.

Olá, Nicolas, como vai?

Que bom que a solução anterior te ajudou! Em relação ao InheritedWidget, ele realmente é usado para compartilhar estado entre widgets sem a necessidade de chamar setState diretamente. Eu usei o setState no exemplo para simplificar a atualização da interface.

Pode ser que o comportamento que você está observando seja devido a atualizações recentes ou mudanças na versão do Flutter. Eu notei que você seguiu a formação, espero que não tenha sido um problema nos seus estudos.

Reitero que o fórum está sempre à disposição para te ajudar!

Siga firme com os seus estudos!

Obrigado pela resposta. A dúvida, de modo geral não atrapalhou meus estudos, mas eu gostaria de ver um exemplo com o InhreritedWidget atualizando sem o uso do setState. Consegui fazer isso com o Provider, BloC e ValueNotifier. Mas só com o IhritedWidget "puro" não consegui.