1
resposta

Problema com future builder não recarrega a tela mesmo transformando em stateful

Fiz o código da mesma maneira que o curso. Ao finalizar o fomulário cadastra no banco. Mas, ao dar o pop não atualiza a tela mesmo seguindo a ideia de mudar pra statefulWidget. Só se abrir a tela novamente. No debug tbm não chama o método findall() Segue abaixo o código da contact_lista.dart

import 'package:bytebankpersistence/database/app_database.dart';
import 'package:bytebankpersistence/model/contact.dart';
import 'package:bytebankpersistence/screens/contact_form.dart';
import 'package:flutter/material.dart';

class ContactsList extends StatefulWidget {
  @override
  State<ContactsList> createState() => _ContactsListState();
}

class _ContactsListState extends State<ContactsList> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Contacts'),
      ),
      body: FutureBuilder<List<Contact>>(
        initialData: List.empty(growable: true),
        future: findAll(),
        builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.none:
              break;
            case ConnectionState.waiting:
              return Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: const [CircularProgressIndicator(), Text('Loading')],
              );
              break;
            case ConnectionState.active:
              // TODO: Handle this case.
              break;
            case ConnectionState.done:
              if (snapshot.hasData) {
                final List<Contact> contacts = snapshot.data;
                return ListView.builder(
                  itemBuilder: (context, index) {
                    final Contact contact = contacts[index];
                    return _contactItem(contact);
                  },
                  itemCount: contacts.length,
                );
                break;
              }
              return const Text('Sem registros');
          }

          return const Text('Unknow error');
        },
      ),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.add),
        onPressed: () => Navigator.of(context)
            .push(MaterialPageRoute(builder: (context) => ContactForm())),
      ),
    );
  }
}

class _contactItem extends StatelessWidget {
  final Contact contact;

  const _contactItem(this.contact);

  @override
  Widget build(BuildContext context) {
    return Card(
      child: ListTile(
        title: Text(
          contact.name?? '',
          style: const TextStyle(fontSize: 24),
        ),
        subtitle: Text(
          contact.accountNumber.toString(),
          style: const TextStyle(fontSize: 26),
        ),
      ),
    );
  }
}
1 resposta

Olá, Fagner.

No Flutter quando tiramos uma tela da pilha de rotas com o método pop(), a tela/widget anterior (ContactsList) que irá se torna a atual não sobre atualização, ela conserva seu estado por ser uma das primeiras tela/widget mais no topo da pilha.

Para reexecutar o FutureBuilder e assim sincronizar os dados com o banco de dados (sqflite) é precisar força um rebuild com o setState, como no seguinte código:

floatingActionButton: FloatingActionButton(
    child: const Icon(Icons.add),
    onPressed: () async {
        await Navigator.of(context).push(MaterialPageRoute(builder: (context) => ContactForm()));
        // Force update (rebuild widget)
        setState(() {});
    }
),