FutureBuilder — ay isang widget sa Flutter na awtomatikong nagtatayo muli ng interface nito batay sa kasalukuyang estado ng AsyncSnapshot na nakuha mula sa ipinadalang Future. Hindi tulad ng manu-manong pagtawag sa setState pagkatapos ng await, ang FutureBuilder ay nagbibigay ng deklaratibong approach: nag-subscribe ito sa Future sa unang pag-render at tumatawag sa builder function sa bawat pagbabago ng estado — pag-load, error, o handa nang data. Ayon sa Flutter API Reference (2026), ang FutureBuilder ay partikular na kapaki-pakinabang para sa pag-load ng data mula sa network, pagbasa mula sa database, at anumang asynchronous na operasyon kung saan ang UI ay kailangang magpakita ng loading indicator, error message, o handa nang content.
Mga Pangunahing Punto
FutureBuilder — ay isang built-in na Flutter widget mula sa widgets package na tumatanggap ng Future<T> at isang builder function. Kapag nagbago ang estado ng Future (nagpapatakbo, natapos na may data, natapos na may error) awtomatikong itinatayo muli ng FutureBuilder ang UI sa pamamagitan ng pagtawag sa builder na may bagong AsyncSnapshot. Tinatanggal nito ang pangangailangan na manu-manong pamahalaan ang loading state sa pamamagitan ng setState at mga flag.
Hindi tulad ng StreamBuilder na gumagana sa mga stream ng data (Stream), ang FutureBuilder ay idinisenyo para sa isang beses na asynchronous na operasyon: HTTP request, pagbasa mula sa file, database query. Ang FutureBuilder mismo ang namamahala ng subscription sa Future: sa unang pagbuo ay pinapatakbo nito ang Future at sinusubaybayan ang pagkumpleto nito. Kapag nawasak ang widget, hindi kinakansela ng FutureBuilder ang Future — ito ay responsibilidad ng developer.
Ayon sa Flutter Cookbook (2026), ang FutureBuilder ay inirerekomenda para sa mga kaso kung saan ang asynchronous na operasyon ay isinasagawa nang isang beses sa pagsisimula ng screen. Para sa mga paulit-ulit na operasyon o stream ng data, gamitin ang StreamBuilder. Ang parehong widget ay sumusunod sa parehong Reactive UI pattern, ngunit ang FutureBuilder ay na-optimize para sa isang beses na mga request.
Ang panloob na implementasyon ng FutureBuilder ay nag-subscribe sa Future sa pamamagitan ng Future.then at catchError. Sa pagsisimula, itinatakda ng FutureBuilder ang connectionState sa ConnectionState.waiting at tinatawagan ang builder na may walang laman na data. Sa matagumpay na pagkumpleto, ang connectionState ay nagbabago sa ConnectionState.done na may data. Sa error, ang snapshot.error ay pinupunan ng error object. Ang bawat pagbabago ay nagti-trigger ng muling pagbuo ng widget.
AsyncSnapshot — ay isang container object na ipinapasa ng FutureBuilder sa builder function sa bawat pagbabago ng estado. Naglalaman ito ng lahat ng impormasyon tungkol sa kasalukuyang status ng asynchronous na operasyon: kung ang pag-load ay nagpapatuloy, anong data ang natanggap, kung may naganap na error. Ang pag-unawa sa AsyncSnapshot ay susi sa tamang pagbuo ng UI gamit ang FutureBuilder.
| Katangian | Uri | Paglalarawan |
|---|---|---|
| connectionState | ConnectionState | Kasalukuyang estado ng koneksyon (none, waiting, active, done) |
| data | T? | Data na natanggap mula sa Future (null hanggang pagkumpleto o sa error) |
| error | Object? | Error object kung ang Future ay natapos na may exception |
| hasData | bool | true kung ang data ay hindi null at ang estado ay ConnectionState.done |
| hasError | bool | true kung ang Future ay natapos na may error |
Enum ConnectionState ay tumutukoy sa yugto ng asynchronous na operasyon. None — paunang estado kapag ang Future ay hindi pa nasisimulan (bihirang ginagamit, karaniwan sa unang pagbuo nang walang initialData). Waiting — ang Future ay tumatakbo, ang data ay hindi pa natatanggap. Active — ginagamit lamang ng StreamBuilder para sa mga stream na may bahagyang data. Done — ang Future ay natapos, ang data ay available sa pamamagitan ng snapshot.data o error sa pamamagitan ng snapshot.error.
Ang tamang pangangasiwa ng lahat ng estado ng AsyncSnapshot sa builder function ay isang mandatoryong kinakailangan para sa production code. Kung hindi mo pangasiwaan ang waiting state, makikita ng user ang walang laman na screen habang naglo-load. Kung hindi mo pangasiwaan ang hasError, makakatanggap ang user ng Exception nang walang paliwanag. Inirerekomendang pattern: suriin ang hasError → suriin ang hasData → default na magpakita ng loading.
FutureBuilder ay maaaring gamitin sa ilang karaniwang pattern, bawat isa ay lumulutas ng isang partikular na gawain. Tingnan natin ang mga pangunahing senaryo: pag-load ng data sa pagsisimula, pag-load na may cache, parallel na mga request, at pangangasiwa ng error na may pag-uulit.
Ang pinakakaraniwang pattern — FutureBuilder sa build method ng StatefulWidget o StatelessWidget. Ang Future ay ipinapasa mula sa initState o direktang ginagawa sa build. Mahalagang huwag gumawa ng Future sa build method sa bawat muling pagbuo — ito ay humahantong sa paulit-ulit na mga request. Gamitin ang Future na naka-save sa field ng State.
Upang maiwasan ang paulit-ulit na mga request, ang FutureBuilder ay maaaring isama sa CachedNetworkImage o lokal na cache. Pagkatapos ng unang pag-load, ang data ay nai-save sa memorya o SharedPreferences, at ang FutureBuilder ay nagpapakita ng naka-cache na data agad, habang pinapa-update ito nang parallel mula sa network. Ito ay nagpapabuti sa UX sa pamamagitan ng agarang pagtugon.
Ayon sa pub.dev (2026), ang pag-cache ay partikular na mahalaga para sa mga imahe at listahan ng data. Ang FutureBuilder na may CachedNetworkImageProvider ay awtomatikong nagpapakita ng naka-cache na imahe, at kung wala — loading indicator na may kasunod na pagpapakita ng na-download na file.
FutureBuilder at manu-manong pamamahala ng estado sa pamamagitan ng setState — dalawang approach sa asynchronous na UI sa Flutter. Bawat isa ay may mga pakinabang at limitasyon. Ang pagpili ay depende sa pagiging kumplikado ng screen at bilang ng mga asynchronous na operasyon.
FutureBuilder ay nananalo sa pagiging simple: hindi na kailangang magdeklara ng mga field para sa loading state, data, at error — lahat ay pinamamahalaan sa pamamagitan ng AsyncSnapshot. Ito ay perpekto para sa mga simpleng screen na may isang asynchronous na operasyon (isang HTTP request, pagbasa ng database). Gayunpaman, sa 5+ asynchronous na operasyon sa isang screen, ang FutureBuilder ay lumilikha ng labis na nesting — nabubuo ang “pyramid” ng mga nested na FutureBuilder.
setState na may manu-manong flag ng estado ay nagbibigay ng higit na kontrol at pagiging madaling basahin sa kumplikadong logic. Para sa mga screen na may maraming dependent na request (i-load ang user → i-load ang kanyang mga order → i-load ang mga detalye ng order) mas mainam na gamitin ang setState na may ChangeNotifier o Bloc. Ayon sa Flutter State Management Guide (2026), para sa mga kumplikadong senaryo inirerekomenda ang paggamit ng Riverpod o Bloc sa halip na FutureBuilder, dahil nagbibigay sila ng mas mahusay na paghihiwalay ng logic at presentasyon.
Tingnan natin ang isang praktikal na halimbawa ng FutureBuilder para sa pag-load ng listahan ng mga user mula sa REST API. Ang code ay nagpapakita ng tamang pangangasiwa ng lahat ng tatlong estado ng AsyncSnapshot: pag-load, error, at handa nang 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());
},
),
);
}
}
Sa halimbawa, FutureBuilder ay humahawak ng lahat ng tatlong estado. Sa error, isang icon na may error message ang ipinapakita. Sa matagumpay na pag-load — ListView na may mga avatar at pangalan. Sa panahon ng pag-load — CircularProgressIndicator. Ang Future ay idineklara bilang field ng klase, na pumipigil sa paulit-ulit na pagtawag sa muling pagbuo. Ang pattern na ito ay sumasaklaw sa 90% ng mga senaryo ng paggamit ng FutureBuilder sa mga mobile application.
Mga Madalas Itanong
FutureBuilder ay tinatawagan ang builder sa bawat pagbabago ng estado ng Future: unang beses sa paggawa (connectionState: none o waiting), ikalawang beses sa pagkumpleto (connectionState: done). Kung ang parent widget ay muling itinayo, ang FutureBuilder ay muling itinayo rin. Upang maiwasan ang paulit-ulit na pagtawag, tiyakin na ang Future ay ginawa sa labas ng build method — kung hindi, bawat tawag sa build ay gumagawa ng bagong Future.
I-save ang Future sa field ng StatefulWidget (sa initState) o gumamit ng memoization. Kung ang Future ay ginawa sa loob ng build method, bawat tawag sa build ay gagawa ng bagong Future, at muling sisimulan ng FutureBuilder ang asynchronous na operasyon. Para sa StatelessWidget, gamitin ang package na cached_future o keep-alive widgets upang ang Future ay maisagawa nang isang beses anuman ang muling pagbuo.
FutureBuilder ay idinisenyo para sa isang beses na asynchronous na operasyon (isang HTTP request, isang pagbasa ng database). StreamBuilder ay gumagana sa mga stream ng data na maaaring magpalabas ng maraming halaga sa paglipas ng panahon (chat, mga update ng presyo, geolokasyon). Sinusuportahan ng StreamBuilder ang ConnectionState.active para sa bahagyang data, habang ang FutureBuilder ay sumusuporta lamang ng waiting at done.
Para sa maraming parallel na Future, gamitin ang Future.wait at ipasa ang resulta sa isang FutureBuilder. Ang Future.wait ay tumatanggap ng listahan ng Future at nagbabalik ng Future<List> — kapag ang lahat ng Future ay natapos, ang builder ay tumatanggap ng array ng mga resulta. Para sa sunod-sunod na mga request, gumamit ng chain ng Future.then sa loob ng isang Future o nested FutureBuilder (hindi gaanong nababasa). Alternatibo — ang package na riverpod na may AsyncValue para sa maraming asynchronous na estado.
FutureBuilder ay hindi awtomatikong kinakansela ang Future. Para sa pagkansela, gamitin ang CancelableOperation mula sa async package o sariling mekanismo sa pamamagitan ng cancelled flag sa State. Sa dispose() itakda ang flag, at pagkatapos ng pagkumpleto ng Future suriin ito bago tumawag ng setState. Bilang alternatibo, gamitin ang package na riverpod na may AutoDispose na awtomatikong kumakansela ng mga asynchronous na operasyon kapag lumalabas sa screen.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din