1
resposta

[Projeto] Desafio de persistência concluído

Na classe Task adicionei o AlertDialog. Infelizmente não consegui fazer a tela ser atualizada ao deletar a tarefa pois o método delete está dentro da classe Task... queimei muito a cabeça para ver como colocar o setState na InitialScreenState ao executar o método, mas não deu.


class _TaskState extends State<Task> {
  bool assetOrNetwork() {
    if (widget.foto.contains('http')) {
      return false;
    }
    return true;
  }

...
                    SizedBox(
                      height: 52,
                      width: 52,
                      child: ElevatedButton(
                          onLongPress: () {
                            removerTarefa(context);
                          },
                          onPressed: () {
                            setState(() {
                              widget.nivel++;
                              TaskDao().save(widget);
                            });
                            //print(widget.nivel);
                          },
                          child: Column(
                            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                            crossAxisAlignment: CrossAxisAlignment.end,
                            children: const [
                              Icon(Icons.arrow_drop_up),
                              Text(
                                'UP',
                                style: TextStyle(fontSize: 12),
                              ),
                            ],
                          )),
                    )
                  ],
                ),
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: SizedBox(
                      width: 200,
                      child: LinearProgressIndicator(
                        color: Colors.white,
                        value: (widget.dificuldade > 0)
                            ? (widget.nivel / widget.dificuldade) / 10
                            : 1,
                      ),
                    ),
                  ),
                  Padding(
                    padding: const EdgeInsets.all(12.0),
                    child: Text(
                      'Nível: ${widget.nivel}',
                      style: const TextStyle(color: Colors.white, fontSize: 16),
                    ),
                  ),
                ],
              ),
            ],
          ),
        ],
      ),
    );
  }

  void removerTarefa(BuildContext context) {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Row(
            children: const [
              Text('Deletar'),
              Icon(Icons.delete_forever),
            ],
          ),
          content: const Text('Tem certeza de que deseja deletar essa tarefa?'),
          actions: <Widget>[
            TextButton(
              child: const Text('Cancelar'),
              onPressed: () {
                Navigator.pop(context);
              },
            ),
            TextButton(
                child: const Text('Deletar'),
                onPressed: () {
                  TaskDao().delete(widget.nome);
                  Navigator.pop(context);
                }),
          ],
        );
      },
    );
  }
}

E atualizei a tabela do banco de dados. Não funcionou de primeira, mas apaguei o cache da aplicação e deu tudo certo.

class TaskDao {
  static String tableSql = 'CREATE TABLE $_tablename('
      '$_name TEXT, '
      '$_difficulty INTEGER, '
      '$_level INTEGER, '
      '$_image TEXT)';

  static const String _tablename = 'TaskTable2';
  static const String _name = 'name';
  static const String _difficulty = 'difficulty';
  static const String _image = 'image';
  static const String _level = 'level';
1 resposta

Olá, Murilo!

Desculpa a demora. Estou respondendo esse tópico para ajudar você e outras pessoas com essa mesma dúvida, e também para organizar o nosso fórum de Flutter.

Parabéns pelo desafio, por tentar fazer e conseguir evoluir essa parte. Muito bom!

Olhando o seu código, parece que o método de exclusão está dentro da classe Task e você está tentando usar o setState na InitialScreenState.

Uma possível solução para esse problema é utilizar callbacks para notificar a tela de que uma tarefa foi deletada. Você pode criar uma função callback na classe Task e passá-la como parâmetro para o AlertDialog. Quando o botão de deletar for pressionado, você chama essa função callback e a tela será atualizada.

Aqui está um exemplo de como você pode implementar essa solução:

  1. Na classe Task, adicione uma função callback chamada "onTaskDeleted":
class Task extends StatefulWidget {
  // ...

  final VoidCallback onTaskDeleted;

  Task({Key? key, required this.onTaskDeleted}) : super(key: key);

  // ...
}
  1. No método "removerTarefa", chame a função callback "onTaskDeleted" quando a tarefa for deletada:
void removerTarefa(BuildContext context) {
  showDialog(
    context: context,
    builder: (BuildContext context) {
      return AlertDialog(
        // ...
        actions: <Widget>[
          // ...
          TextButton(
            child: const Text('Deletar'),
            onPressed: () {
              TaskDao().delete(widget.nome);
              widget.onTaskDeleted(); // Chama a função callback
              Navigator.pop(context);
            },
          ),
        ],
      );
    },
  );
}
  1. Na classe InitialScreenState, passe a função callback para a classe Task:
class InitialScreenState extends State<InitialScreen> {
  // ...

  void _atualizarTela() {
    setState(() {
      // Atualize os dados da tela aqui
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // ...
      body: Task(
        // ...
        onTaskDeleted: _atualizarTela, // Passe a função callback aqui
      ),
    );
  }

  // ...
}

Dessa forma, quando uma tarefa for deletada, a função callback "_atualizarTela" será chamada, o setState será executado e a tela será atualizada.

Espero ter ajudado e bons estudos!