FutureBuilder — je vestavěný widget ve Flutter, který automaticky přestavuje své rozhraní na základě aktuálního stavu AsyncSnapshot získaného z předaného Future. Na rozdíl od ručního volání setState po await, FutureBuilder poskytuje deklarativní přístup: při prvním vykreslení se přihlásí k odběru Future a při každé změně stavu — načítání, chyba nebo hotová data — volá funkci builder. Podle Flutter API Reference (2026) je FutureBuilder obzvláště užitečný pro načítání dat ze sítě, čtení z databáze a veškeré asynchronní operace, kde UI musí zobrazovat indikátor načítání, chybovou zprávu nebo hotový obsah.
Hlavní body
FutureBuilder — je vestavěný widget Flutter z balíčku widgets, který přijímá Future<T> a funkci builder. Když se stav Future změní (probíhá, dokončeno s daty, dokončeno s chybou) FutureBuilder automaticky přestaví UI voláním builder s novým AsyncSnapshot. Tím odpadá nutnost ruční správy stavu načítání přes setState a příznaky.
Na rozdíl od StreamBuilder, který pracuje s datovými toky (Stream), je FutureBuilder určen pro jednorázové asynchronní operace: HTTP požadavek, čtení ze souboru, dotaz do databáze. FutureBuilder sám spravuje odběr Future: při prvním sestavení spustí Future a sleduje jeho dokončení. Při zničení widgetu FutureBuilder Future neruší — to je odpovědnost vývojáře.
Podle Flutter Cookbook (2026) se FutureBuilder doporučuje pro případy, kdy se asynchronní operace spouští jednou při inicializaci obrazovky. Pro opakující se operace nebo datové toky použijte StreamBuilder. Oba widgety následují stejný vzor Reactive UI, ale FutureBuilder je optimalizován pro jednorázové požadavky.
Interní implementace FutureBuilder se přihlásí k odběru Future pomocí Future.then a catchError. Při startu FutureBuilder nastaví connectionState na ConnectionState.waiting a zavolá builder s prázdnými daty. Při úspěšném dokončení se connectionState změní na ConnectionState.done s daty. Při chybě se snapshot.error naplní objektem chyby. Každá změna spustí přestavbu widgetu.
AsyncSnapshot — je kontejnerový objekt, který FutureBuilder předává funkci builder při každé změně stavu. Obsahuje všechny informace o aktuálním stavu asynchronní operace: zda načítání probíhá, jaká data byla přijata, zda došlo k chybě. Porozumění AsyncSnapshot je klíčem ke správnému sestavení UI s FutureBuilder.
| Vlastnost | Typ | Popis |
|---|---|---|
| connectionState | ConnectionState | Aktuální stav připojení (none, waiting, active, done) |
| data | T? | Data přijatá z Future (null do dokončení nebo při chybě) |
| error | Object? | Objekt chyby, pokud Future skončilo výjimkou |
| hasData | bool | true, pokud data nejsou null a stav je ConnectionState.done |
| hasError | bool | true, pokud Future skončilo chybou |
Enum ConnectionState určuje fázi asynchronní operace. None — počáteční stav, když Future ještě nebylo spuštěno (používá se zřídka, obvykle při prvním sestavení bez initialData). Waiting — Future běží, data ještě nebyla přijata. Active — používá se pouze StreamBuilder pro streamy s částečnými daty. Done — Future je dokončeno, data jsou dostupná přes snapshot.data nebo chyba přes snapshot.error.
Správné zpracování všech stavů AsyncSnapshot ve funkci builder je povinným požadavkem pro produkční kód. Pokud nezpracujete stav waiting, uživatel uvidí prázdnou obrazovku během načítání. Pokud nezpracujete hasError, uživatel dostane Exception bez vysvětlení. Doporučený vzor: kontrola hasError → kontrola hasData → výchozí zobrazení načítání.
FutureBuilder lze použít v několika standardních vzorcích, z nichž každý řeší konkrétní úkol. Podívejme se na hlavní scénáře: načítání dat při inicializaci, načítání s cache, paralelní požadavky a zpracování chyb s opakováním.
Nejčastější vzor — FutureBuilder v metodě build StatefulWidget nebo StatelessWidget. Future je předáno z initState nebo vytvořeno přímo v build. Je důležité nevytvářet Future v metodě build při každém přestavění — to vede k opakovaným požadavkům. Použijte Future uložené v poli State.
Aby se předešlo opakovaným požadavkům, lze FutureBuilder kombinovat s CachedNetworkImage nebo lokální cache. Po prvním načtení se data uloží do paměti nebo SharedPreferences a FutureBuilder zobrazí cacheovaná data okamžitě, zatímco je paralelně aktualizuje ze sítě. To zlepšuje UX okamžitou odezvou.
Podle pub.dev (2026) je cacheování obzvláště důležité pro obrázky a seznamy dat. FutureBuilder s CachedNetworkImageProvider automaticky zobrazí cacheovaný obrázek, a při jeho absenci — indikátor načítání s následným zobrazením staženého souboru.
FutureBuilder a ruční správa stavu přes setState — dva přístupy k asynchronnímu UI ve Flutter. Každý má své výhody a omezení. Volba závisí na složitosti obrazovky a počtu asynchronních operací.
FutureBuilder vítězí v jednoduchosti: není potřeba deklarovat pole pro stav načítání, data a chybu — vše je spravováno přes AsyncSnapshot. Je ideální pro jednoduché obrazovky s jednou asynchronní operací (jeden HTTP požadavek, čtení z databáze). Při 5+ asynchronních operacích na jedné obrazovce však FutureBuilder vytváří nadměrné vnoření — vzniká „pyramida" vnořených FutureBuilderů.
setState s ručními příznaky stavu poskytuje větší kontrolu a čitelnost při složité logice. Pro obrazovky s mnoha závislými požadavky (načíst uživatele → načíst jeho objednávky → načíst detaily objednávky) je lepší použít setState s ChangeNotifier nebo Bloc. Podle Flutter State Management Guide (2026) se pro složité scénáře doporučuje používat Riverpod nebo Bloc místo FutureBuilder, protože poskytují lepší oddělení logiky a prezentace.
Podívejme se na praktický příklad FutureBuilder pro načítání seznamu uživatelů z REST API. Kód demonstruje správné zpracování všech tří stavů AsyncSnapshot: načítání, chyba a hotová data.
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('Users')),
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('Error: ${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());
},
),
);
}
}
V příkladu FutureBuilder zpracovává všechny tři stavy. Při chybě se zobrazí ikona s chybovou zprávou. Při úspěšném načtení — ListView s avatary a jmény. Během načítání — CircularProgressIndicator. Future je deklarováno jako pole třídy, což zabraňuje opakovanému volání při přestavbě. Tento vzor pokrývá 90% scénářů použití FutureBuilder v mobilních aplikacích.
Často kladené otázky
FutureBuilder volá builder při každé změně stavu Future: poprvé při vytvoření (connectionState: none nebo waiting), podruhé při dokončení (connectionState: done). Pokud se rodičovský widget přestaví, FutureBuilder se také přestaví. K zabránění opakovaným voláním se ujistěte, že Future je vytvořeno mimo metodu build — jinak každé volání build vytvoří nové Future.
Uložte Future do pole StatefulWidget (v initState) nebo použijte memoizaci. Pokud je Future vytvořeno uvnitř metody build, každé volání build vytvoří nové Future a FutureBuilder restartuje asynchronní operaci. Pro StatelessWidget použijte balíček cached_future nebo keep-alive widgety, aby se Future spustilo jednou bez ohledu na přestavby.
FutureBuilder je určen pro jednorázové asynchronní operace (jeden HTTP požadavek, jedno čtení z databáze). StreamBuilder pracuje s datovými toky, které mohou v čase emitovat mnoho hodnot (chat, aktualizace cen, geolokace). StreamBuilder podporuje ConnectionState.active pro částečná data, zatímco FutureBuilder podporuje pouze waiting a done.
Pro několik paralelních Future použijte Future.wait a předejte výsledek jednomu FutureBuilder. Future.wait přijímá seznam Future a vrací Future<List> — když jsou všechna Future dokončena, builder obdrží pole výsledků. Pro sekvenční požadavky použijte řetěz Future.then uvnitř jednoho Future nebo vnořené FutureBuilder (méně čitelné). Alternativa — balíček riverpod s AsyncValue pro vícenásobné asynchronní stavy.
FutureBuilder neruší Future automaticky. Ke zrušení použijte CancelableOperation z balíčku async nebo vlastní mechanismus pomocí příznaku cancelled ve State. V dispose() nastavte příznak a po dokončení Future jej zkontrolujte před voláním setState. Alternativně použijte balíček riverpod s AutoDispose, který automaticky ruší asynchronní operace při opuštění obrazovky.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také