Olá, Douglas! Boa noite!
De "chato" você não tem nada, pelo contrário! Essa sua proatividade em querer entender e resolver os problemas antes de seguir em frente é uma característica excelente para um desenvolvedor. É justamente essa curiosidade e a busca por soluções que te farão um profissional ainda melhor. Parabéns por essa mentalidade!
Sobre o seu problema de loop infinito e o ConnectionState.waiting na InicialScreen, especialmente ao iniciar a aplicação, mas funcionando no hot reload, isso geralmente indica um problema na forma como a inicialização assíncrona está sendo tratada, ou como a reconstrução do widget (build) está reagindo ao estado da conexão.
Pelo seu relato, as causas mais comuns para esse tipo de comportamento são:
Chamada de Função Assíncrona no Lugar Errado: Chamar uma função assíncrona (como uma leitura de banco de dados ou API) diretamente no build do widget sem um FutureBuilder ou StreamBuilder adequado, ou sem gerenciar o ciclo de vida corretamente (initState, dispose), pode levar a rebuilds contínuos.
Estado Mal Gerenciado: Um setState sendo chamado repetidamente em um loop ou uma condição que nunca é satisfeita, fazendo com que o widget seja reconstruído infinitamente.
Future/Stream não Atualizado: Se o Future ou Stream que seu FutureBuilder/StreamBuilder está observando não for o mesmo objeto após um rebuild, ele pode re-executar a operação assíncrona. Isso é um erro comum: criar um Future novo dentro do método build. O Future deve ser criado uma única vez, preferencialmente no initState ou passado de um widget pai.
Analisando o seu repositório que você compartilhou (https://github.com/donsilva-dev/task.git), vou verificar o código da InicialScreen e como você está gerenciando a leitura dos dados.
Sugestões enquanto analiso (ou se você quiser dar uma olhada antes):
Verifique onde o Future é criado: Se você usa um FutureBuilder, certifique-se de que o future que ele espera não está sendo criado dentro do método build da sua InicialScreen. Ele deve ser criado uma única vez no initState ou fora do build (como um campo final da classe State).
// Exemplo de como DEVE ser:
class _InicialScreenState extends State<InicialScreen> {
late Future<List<Task>> _tasksFuture; // Declare o Future
@override
void initState() {
super.initState();
_tasksFuture = TaskDao().findAll(); // Inicialize no initState
}
@override
Widget build(BuildContext context) {
return Scaffold(
// ...
body: FutureBuilder<List<Task>>(
future: _tasksFuture, // Use o Future criado uma vez
builder: (context, snapshot) {
// ...
},
),
);
}
}
Logs mais detalhados: Adicione mais print statements dentro do FutureBuilder, especialmente dentro de cada ConnectionState (none, waiting, active, done) para ver exatamente qual estado está se repetindo.