FutureBuilder — ce este, lucrul cu Future în Flutter

Autor: IT Sectr Publicat: 2026-07-02 Timp de citire: 8 min

FutureBuilder — este un widget în Flutter care reconstruiește automat interfața pe baza stării curente a AsyncSnapshot, obținut din Future-ul transmis. Spre deosebire de apelarea manuală a setState după await, FutureBuilder oferă o abordare declarativă: se abonează la Future la prima randare și apelează funcția builder la fiecare schimbare de stare — încărcare, eroare sau date gata. Conform Flutter API Reference (2026), FutureBuilder este util în special pentru încărcarea datelor din rețea, citirea din baza de date și orice operații asincrone unde UI trebuie să afișeze un indicator de încărcare, un mesaj de eroare sau conținut gata.

Principalele puncte

  • FutureBuilder — widget Flutter pentru construirea UI pe baza stării Future prin AsyncSnapshot (none, waiting, active, done)
  • AsyncSnapshot — obiect care conține starea curentă a operației asincrone: connectionState, data și error
  • builder — funcția callback apelată la fiecare schimbare de stare a Future pentru reconstruirea UI
  • Gestionarea erorilor — AsyncSnapshot.hasError permite afișarea unei interfețe de rezervă în caz de eșec al operației asincrone
  • ConnectionState — enum cu patru valori: none (fără operație), waiting (așteptare), active (flux), done (finalizat)

Ce este FutureBuilder în Flutter

FutureBuilder — este un widget încorporat Flutter din pachetul widgets, care primește Future<T> și o funcție builder. La schimbarea stării Future (se execută, finalizat cu date, finalizat cu eroare) FutureBuilder reconstruiește automat UI, apelând builder cu noul AsyncSnapshot. Aceasta elimină necesitatea gestionării manuale a stării de încărcare prin setState și flag-uri.

Spre deosebire de StreamBuilder, care lucrează cu fluxuri de date (Stream), FutureBuilder este destinat operațiilor asincrone unice: cerere HTTP, citire din fișier, interogare bază de date. FutureBuilder gestionează singur abonarea la Future: la prima construire pornește Future și urmărește finalizarea acestuia. La distrugerea widgetului, FutureBuilder nu anulează Future — aceasta este responsabilitatea dezvoltatorului.

Conform Flutter Cookbook (2026), FutureBuilder este recomandat pentru cazurile în care operația asincronă se lansează o dată la inițializarea ecranului. Pentru operații repetitive sau fluxuri de date, utilizați StreamBuilder. Ambele widgeturi urmează același pattern Reactive UI, dar FutureBuilder este optimizat pentru cereri unice.

Cum funcționează FutureBuilder sub capotă

Implementarea internă a FutureBuilder se abonează la Future prin Future.then și catchError. La pornire, FutureBuilder setează connectionState la ConnectionState.waiting și apelează builder cu date goale. La finalizarea cu succes, connectionState se schimbă în ConnectionState.done cu date. La eroare, snapshot.error este populat cu obiectul de eroare. Fiecare schimbare declanșează reconstruirea widgetului.

AsyncSnapshot: stări și proprietăți

AsyncSnapshot — este un obiect-container pe care FutureBuilder îl transmite funcției builder la fiecare schimbare de stare. Conține toate informațiile despre statusul curent al operației asincrone: dacă încărcarea este în curs, ce date au fost primite, dacă a apărut o eroare. Înțelegerea AsyncSnapshot este cheia construirii corecte a UI cu FutureBuilder.

ProprietateTipDescriere
connectionStateConnectionStateStarea curentă a conexiunii (none, waiting, active, done)
dataT?Datele primite de la Future (null până la finalizare sau la eroare)
errorObject?Obiectul de eroare dacă Future s-a finalizat cu excepție
hasDatabooltrue dacă data nu este null și starea este ConnectionState.done
hasErrorbooltrue dacă Future s-a finalizat cu eroare

ConnectionState: patru stări ale operației asincrone

Enum-ul ConnectionState determină etapa operației asincrone. None — starea inițială când Future nu a fost încă lansat (folosit rar, de obicei la prima construire fără initialData). Waiting — Future se execută, datele nu au fost încă primite. Active — folosit doar de StreamBuilder pentru fluxuri cu date parțiale. Done — Future s-a finalizat, datele sunt disponibile prin snapshot.data sau eroarea prin snapshot.error.

Gestionarea corectă a tuturor stărilor AsyncSnapshot în funcția builder — o cerință obligatorie pentru codul de producție. Dacă nu gestionați starea waiting, utilizatorul va vedea un ecran gol în timpul încărcării. Dacă nu gestionați hasError, utilizatorul va primi o Exception fără explicație. Pattern-ul recomandat: verificare hasError → verificare hasData → implicit afișare încărcare.

Pattern-uri de utilizare FutureBuilder

FutureBuilder poate fi utilizat în mai multe pattern-uri standard, fiecare rezolvând o sarcină specifică. Să analizăm scenariile principale: încărcarea datelor la inițializare, încărcarea cu cache, cereri paralele și gestionarea erorilor cu reîncercare.

Încărcarea datelor la inițializarea ecranului

Cel mai comun pattern — FutureBuilder în metoda build a StatefulWidget sau StatelessWidget. Future este transmis din initState sau creat direct în build. Este important să nu creați Future în metoda build la fiecare reconstruire — aceasta duce la cereri repetate. Utilizați Future salvat în câmpul State.

Încărcarea cu cache și actualizare

Pentru a preveni cererile repetate, FutureBuilder poate fi combinat cu CachedNetworkImage sau cache local. După prima încărcare, datele sunt salvate în memorie sau SharedPreferences, iar FutureBuilder afișează datele din cache instantaneu, actualizându-le în paralel din rețea. Aceasta îmbunătățește UX prin răspuns instantaneu.

Conform pub.dev (2026), cache-ul este deosebit de relevant pentru imagini și liste de date. FutureBuilder cu CachedNetworkImageProvider afișează automat imaginea din cache, iar în lipsa acesteia — un indicator de încărcare cu afișarea ulterioară a fișierului descărcat.

FutureBuilder vs setState: ce să alegem

FutureBuilder și gestionarea manuală a stării prin setState — două abordări ale UI-ului asincron în Flutter. Fiecare are avantajele și limitările sale. Alegerea depinde de complexitatea ecranului și numărul de operații asincrone.

FutureBuilder câștigă prin simplitate: nu trebuie declarate câmpuri pentru starea de încărcare, date și eroare — totul este gestionat prin AsyncSnapshot. Este ideal pentru ecrane simple cu o singură operație asincronă (o cerere HTTP, citire din bază de date). Totuși, la 5+ operații asincrone pe un ecran, FutureBuilder creează o cuibărire excesivă — se formează o „piramidă" de FutureBuilder-uri cuibărite.

setState cu flag-uri manuale de stare oferă mai mult control și lizibilitate în logica complexă. Pentru ecrane cu multiple cereri dependente (încărcare utilizator → încărcare comenzi → încărcare detalii comandă) este mai bine să folosiți setState cu ChangeNotifier sau Bloc. Conform Flutter State Management Guide (2026), pentru scenarii complexe se recomandă utilizarea Riverpod sau Bloc în loc de FutureBuilder, deoarece asigură o separare mai bună a logicii de prezentare.

Exemplu FutureBuilder cu încărcare date din rețea

Să analizăm un exemplu practic de FutureBuilder pentru încărcarea unei liste de utilizatori dintr-un REST API. Codul demonstrează gestionarea corectă a tuturor celor trei stări AsyncSnapshot: încărcare, eroare și date gata.

dart
class UserListPage extends StatefulWidget {
  const UserListPage({super.key});

  @override
  State<UserListPage> createState() => _UserListPageState();
}

class _UserListPageState extends State<UserListPage> {
  final Future<List<User>> usersFuture = UserRepository().fetchUsers();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Utilizatori')),
      body: FutureBuilder<List<User>>(
        future: usersFuture,
        builder: (context, AsyncSnapshot<List<User>> snapshot) {
          if (snapshot.hasError) {
            return Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  const Icon(Icons.error_outline, size: 48, color: Colors.red),
                  const SizedBox(height: 16),
                  Text('Eroare: ${snapshot.error}'),
                ],
              ),
            );
          }

          if (snapshot.hasData) {
            final users = snapshot.data!;
            return ListView.builder(
              itemCount: users.length,
              itemBuilder: (context, index) {
                return ListTile(
                  leading: CircleAvatar(backgroundImage: NetworkImage(users[index].avatarUrl)),
                  title: Text(users[index].name),
                  subtitle: Text(users[index].email),
                );
              },
            );
          }

          return const Center(child: CircularProgressIndicator());
        },
      ),
    );
  }
}

În exemplu, FutureBuilder gestionează toate cele trei stări. La eroare se afișează o iconiță cu mesajul de eroare. La încărcare cu succes — ListView cu avataruri și nume. În timpul încărcării — CircularProgressIndicator. Future este declarat ca câmp al clasei, ceea ce previne re-apelarea la reconstruire. Acest pattern acoperă 90% din scenariile de utilizare a FutureBuilder în aplicații mobile.

Întrebări frecvente

De ce FutureBuilder apelează builder de mai multe ori?

FutureBuilder apelează builder la fiecare schimbare de stare a Future: prima dată la creare (connectionState: none sau waiting), a doua oară la finalizare (connectionState: done). Dacă widgetul părinte se reconstruiește, FutureBuilder se reconstruiește și el. Pentru a preveni apelurile repetate, asigurați-vă că Future este creat în afara metodei build — altfel fiecare apel build creează un nou Future.

Cum prevenim o cerere repetată la reconstruire?

Salvați Future în câmpul StatefulWidget (în initState) sau folosiți memoizare. Dacă Future este creat în interiorul metodei build, fiecare apel build va crea un nou Future, iar FutureBuilder va reporni operația asincronă. Pentru StatelessWidget, utilizați pachetul cached_future sau widget-uri keep-alive pentru ca Future să se execute o singură dată indiferent de reconstruiri.

Cu ce se deosebește FutureBuilder de StreamBuilder?

FutureBuilder este destinat operațiilor asincrone unice (o cerere HTTP, o citire din bază de date). StreamBuilder lucrează cu fluxuri de date care pot emite multiple valori în timp (chat, actualizări de preț, geolocație). StreamBuilder suportă ConnectionState.active pentru date parțiale, iar FutureBuilder — doar waiting și done.

Cum folosim FutureBuilder cu mai multe Future?

Pentru mai multe Future paralele, folosiți Future.wait și transmiteți rezultatul într-un singur FutureBuilder. Future.wait primește o listă de Future și returnează Future<List> — când toate Future-urile sunt finalizate, builder primește un array de rezultate. Pentru cereri secvențiale, folosiți un lanț Future.then în interiorul unui singur Future sau FutureBuilder-uri cuibărite (mai puțin lizibil). Alternativa — pachetul riverpod cu AsyncValue pentru stări asincrone multiple.

Cum anulăm Future la ieșirea din ecran?

FutureBuilder nu anulează Future automat. Pentru anulare, folosiți CancelableOperation din pachetul async sau propriul mecanism prin flag-ul cancelled în State. În dispose() setați flag-ul, iar după finalizarea Future verificați-l înainte de a apela setState. Alternativ, folosiți pachetul riverpod cu AutoDispose, care anulează automat operațiile asincrone la ieșirea din ecran.

Rezumat

  • FutureBuilder — widget Flutter pentru construirea declarativă a UI pe baza stării Future prin AsyncSnapshot (waiting, done, error)
  • AsyncSnapshot — container cu connectionState, data și error; obligatoriu pentru gestionarea corectă a tuturor stărilor operației asincrone
  • builder — callback cu trei ramuri: hasError (afișare eroare), hasData (afișare date), default (indicator de încărcare)
  • FutureBuilder vs setState — FutureBuilder mai simplu pentru o operație, setState cu Bloc/Riverpod mai bun pentru logică complexă cu cereri multiple
  • Prevenirea cererilor repetate — Future trebuie să fie câmp State, nu-l creați în metoda build pentru a evita repornirea la fiecare reconstruire
  • Anularea Future — FutureBuilder nu anulează Future la dispose; folosiți CancelableOperation sau un flag de anulare pentru a preveni setState după distrugere
  • Future-uri multiple — pentru cereri paralele folosiți Future.wait cu un singur FutureBuilder; pentru secvențiale — lanțuri într-un singur Future

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și