StreamBuilder — asinxron oqimdan yangi ma'lumotlar olinganda interfeysni avtomatik qayta quradigan Flutter vidjeti. FutureBuilder'dan farqli o'laroq, bir martalik natija bilan ishlaydigan StreamBuilder, Stream'ning butun hayotiy sikli davomida UI'ni uzluksiz yangilashni qo'llab-quvvatlaydi. Flutter (2026) rasmiy hujjatlariga ko'ra, StreamBuilder real vaqt ilovalarida ishlatiladi: chatlar, yangiliklar lentalari, sensor monitoringi va moliyaviy tickerlar. Bu UI ma'lumotlar holatini qo'lda setState chaqiruvlarisiz aks ettiruvchi reaktiv dasturlashning asosiy vositasidir.
Asosiy
StreamBuilder — Flutter SDK paketidagi Stream'ga obuna bo'ladigan va oqimning har bir yangi hodisasida o'zining bola elementini qayta quradigan vidjet. StreamBuilder Stream obyektini qabul qiladi va oqimdan olingan oxirgi snapshot asosida vidjet qaytaradi.
Flutter arxitekturasida StreamBuilder UI qurilishini ma'lumotlar holatidan ajratadigan Builder-vidjetlar guruhiga kiradi. Holat o'zgarishi aniq setState chaqiruvini talab qiladigan StatefulWidget'dan farqli o'laroq, StreamBuilder asinxron hodisalarga avtomatik reaksiya beradi, bu kodni soddalashtiradi va sinxronizatsiya xatolari xavfini kamaytiradi.
FutureBuilder'dan farqli o'laroq, bitta asinxron qiymatni qayta ishlaydigan StreamBuilder uzluksiz ma'lumot oqimlari uchun mo'ljallangan. FutureBuilder birinchi natijani olgandan keyin tugaydi, StreamBuilder esa oqimni tinglashda davom etadi va har bir yangi hodisada UI'ni yangilaydi.
StreamBuilder ma'lumotlar uzluksiz keladigan barcha stsenariylarda qo'llaniladi: WebSocket ulanishlari, sensor chaqiruvlari, Firebase bildirishnomalari, Bluetooth hodisalar navbatlari va BLoC orqali ilova holatini uzatish. GitHub'dagi (2025) Flutter loyihalari tahliliga ko'ra, StreamBuilder FutureBuilder va LayoutBuilder bilan birga eng ko'p ishlatiladigan Builder-vidjetlar uchligiga kiradi.
Xulosa: StatefulWidget orqali qo'lda holat boshqaruvidan qochib, UI doimiy o'zgaruvchan ma'lumotlarni aks ettirishi kerak bo'lgan hamma joyda StreamBuilder'dan foydalaning.
StreamBuilder qurilish vaqtida Stream'ga obuna bo'ladi va vidjet yo'q qilinganda obunani bekor qiladi. Stream har safar hodisa chiqarganda, StreamBuilder yangi AsyncSnapshot oladi va UI'ni qayta qurish uchun builder funksiyasini chaqiradi.
Jarayon uch bosqichdan iborat. Birinchi: StreamBuilder stream.listen metodi orqali uzatilgan Stream'ga obuna yaratadi. Ikkinchi: har bir hodisada StreamBuilder ichki AsyncSnapshot'ni yangilaydi va vidjetni qayta qurish uchun “iflos” deb belgilaydi. Uchinchi: framework yangi snapshot bilan builder funksiyasini chaqiradi va UI joriy ma'lumotlarni ko'rsatadi.
Muhim: StreamBuilder ichki tarzda StreamSubscription dan foydalanadi. Agar Stream to'g'ridan-to'g'ri uzatilsa, StreamBuilder inicializatsiyada bir marta obuna bo'ladi. Agar Stream o'zgarsa (masalan, ota-onaning qayta qurilishida), StreamBuilder eski oqimdan obunani bekor qiladi va yangisiga obuna bo'ladi. Bu xatti-harakat initialData va buildWhen parametrlari bilan boshqariladi, bu qayta qurishlar sonini optimallashtirish imkonini beradi.
Xulosa: obunaning hayotiy siklini tushunish StreamBuilder'dan to'g'ri foydalanishning asosidir. Oqimlarni noto'g'ri boshqarish xotira oqishiga yoki UI'da eskirgan ma'lumotlarga olib keladi.
AsyncSnapshot obyektining connectionState xususiyati StreamBuilder oqim bilan ishning qaysi bosqichida ekanligini aniqlaydi. To'rt holat farqlanadi: none, waiting, active, done.
None — Stream hali ma'lumotlarni uzatishni boshlamagan boshlang'ich holat. Bu holatda snapshot.connectionState ConnectionState.none ga teng, snapshot.data esa null. Odatda bu holatda placeholder yoki birinchi hodisani kutish ko'rsatiladi. Agar Stream boshlang'ich ma'lumotlarni taqdim qilmasa, StreamBuilder shu holatdan boshlaydi.
Waiting — asinxron oqimdan ma'lumot kutish holati. Stream faol, ammo ma'lumotlar hali kelmagan. Bu holat, masalan, tarmoqdan ma'lumot yuklanayotganda yoki uzoq muddatli ulanish ochilganda yuzaga keladi. Bu holatda odatda CircularProgressIndicator yoki yuklash skeleti ko'rsatiladi.
Active — oqim ma'lumotlarni chiqaradi va UI joriy axborotni ko'rsatadi. Bu holatda snapshot.hasData true, snapshot.data esa oqimdagi oxirgi qiymatni o'z ichiga oladi. Agar Stream Broadcast Stream bo'lsa, faol holat yangi ma'lumotlarni kutish bilan birga mavjud bo'lishi mumkin.
Done — oqim tugallangan, yangi ma'lumotlar bo'lmaydi. Snapshot.data oqim yopilishidan oldin uzatilgan oxirgi qiymatni o'z ichiga oladi. Agar oqim muvaffaqiyatli tugagan bo'lsa, snapshot.hasError false. Bu holat yakuniy natijani ko'rsatish uchun ishlatiladi: “Yuklash tugallandi” xabari yoki keyingi ekranga o'tish.
Xulosa: StreamBuilder orqali UI qurishda interfeys yuklash, ma'lumotlar, xatolar va tugallanishni to'g'ri ko'rsatishi uchun barcha to'rt holatni qayta ishlash kerak.
StreamController — dart:async paketidagi Stream yaratuvchi va boshqaruvchi sinf. StreamController ma'lumotlarni qo'shish, xatolarni qayta ishlash va oqimni yopish, uning hayotiy siklini nazorat qilish imkonini beradi.
StreamController ikki turda bo'ladi: single-subscription (bir obunachi) va broadcast (bir necha obunachi). Single-subscription boshqaruvchi bir vaqtning o'zida faqat bitta tinglovchini qabul qiladi — qayta obuna bo'lish istisnoga sabab bo'ladi. Broadcast boshqaruvchi bir nechta StreamBuilder'ga bir vaqtda bitta oqimni tinglashga imkon beradi, bu BLoC va ilovaning umumiy holati uchun foydali.
StreamController<T>.broadcast() orqali StreamController yaratilganda, birinchi obunadan oldin qo'shilgan ma'lumotlar yangi obunachiga takrorlanmaydi. Ulanishda oxirgi qiymatni olish kerak bo'lsa, rxdart paketidagi BehaviourSubject ishlatiladi, u oxirgi hodisani keshga oladi.
Boshqaruvchi bilan ish tugagandan so'ng controller.close() chaqirilishi kerak. Close chaqirilmasligi resurs oqishiga olib keladi: oqim ochiq qoladi, obunachilar xotirada qoladi va GC bog'liq obyektlarni bo'shatmaydi.
Xulosa: StreamController'ni aniq hayotiy sikl boshqaruvi bilan ishlating. Single-subscription oqimlari uchun standart boshqaruvchi, umumiy holat uchun broadcast boshqaruvchi yoki BehaviourSubject'dan foydalaning.
Misol 1 StreamController va StreamBuilder yordamida orqaga hisoblash taymerini namoyish etadi.
import 'dart:async';
class TimerWidget extends StatefulWidget {
const TimerWidget({super.key});
final StreamController<int> controller = StreamController<int>();
void startTimer() {
int count = 0;
Timer.periodic(Duration(seconds: 1), (timer) {
controller.sink.add(count++);
if (count > 10) {
controller.close();
timer.cancel();
}
});
}
}
Misolda 1 soniya interval bilan 0 dan 10 gacha raqamlarni yaratish uchun boshqaruvchi yaratiladi. 10 ga yetgandan so'ng close chaqiriladi va oqim tugaydi. Ushbu boshqaruvchining stream'iga obuna bo'lgan StreamBuilder har bir yangi qiymatni ko'rsatadi.
Misol 2 — bir necha manbadan ma'lumotlarni ko'rsatish uchun Broadcast Stream bilan StreamBuilder'dan foydalanish.
final StreamController<String> broadcastController =
StreamController<String>.broadcast();
StreamBuilder<String>(
stream: broadcastController.stream,
initialData: 'Waiting for data...',
builder: (context, AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
}
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
}
return Text('Data: ${snapshot.data}');
},
)
Ikkinchi misol barcha holatlarni qayta ishlashni ko'rsatadi: dastlabki ko'rsatish uchun initialData, yuklash indikatori uchun waiting, xatolar uchun hasError va muvaffaqiyatli natija uchun data. Bu naqsh StreamBuilder bilan ishlab chiqarish kodining standartidir.
Xulosa: birinchi daqiqada bo'sh ekrandan qochish uchun initialData'dan foydalaning va xatolarni foydalanuvchiga to'g'ri ko'rsatish uchun har doim hasError'ni qayta ishlang.
Xato 1: ota-onaning har bir qayta qurilishida yangi Stream yaratish. Agar Stream har bir qurilishda yangi obyekt yaratadigan ifoda orqali uzatilsa, StreamBuilder eskisidan obunani bekor qiladi va yangi oqimga obuna bo'ladi, cheksiz qayta qurish siklini keltirib chiqaradi. Yechim: remembered o'zgaruvchisi yoki barqaror Stream bilan StatefulWidget'dan foydalaning.
Xato 2: xatolarni qayta ishlashning yo'qligi. Stream controller.sink.addError orqali xatolarni chiqarishi mumkin va agar builder snapshot.hasError'ni tekshirmasa, foydalanuvchi bo'sh ekran yoki cheksiz yuklashni ko'radi. Yechim: har doim hasError'ni tekshiring va tushunarli xabarni ko'rsating.
Xato 3: yopilmagan StreamController sababli xotira oqishi. Agar boshqaruvchi dispose'da yopilmasa, oqim mavjud bo'lishda davom etadi va GC xotirani bo'shatmaydi. Yechim: dispose'da controller.close() ni chaqiring va yakuniy harakatlar uchun done hodisasini tinglang.
Xato 4: sekin builder funksiyasi bilan StreamBuilder'dan foydalanish. Builder oqimning har bir hodisasida chaqirilganligi sababli, uning ichidagi og'ir hisob-kitoblar kadrlarning o'tkazib yuborilishiga olib keladi. Yechim: hisob-kitoblarni alohida izolyatorga o'tkazing yoki ma'lumotlarni o'zgartirish uchun Stream.map dan foydalaning.
Xulosa: StreamBuilder kuchli, ammo talabchan vositadir. Oqimning hayotiy siklini kuzating, xatolarni qayta ishlang va builder'da og'ir operatsiyalardan qoching.
Tez-tez beriladigan savollar
FutureBuilder bir martalik asinxron natija uchun mo'ljallangan: Future'ga obuna bo'ladi, bitta qiymat oladi va ishni tugatadi. StreamBuilder vaqt davomida ko'p qiymatlarni chiqarishi mumkin bo'lgan Stream'ga obuna bo'ladi va har bir yangi hodisada UI'ni qayta quradi.
AsyncSnapshot — joriy obuna holatini (connectionState), oxirgi olingan qiymatni (data) va agar oqim istisno chiqargan bo'lsa, xato obyektini (error) o'z ichiga olgan o'zgarmas obyekt.
Xato builder funksiyasidagi snapshot.hasError va snapshot.error xususiyatlari orqali qayta ishlanadi. Agar oqim sink.addError metodi bilan xato chiqarsa, AsyncSnapshot error oladi va builder tegishli xabar yoki zaxira UI ko'rsatishi kerak.
Ha, agar Stream broadcast bo'lsa (StreamController.broadcast orqali yaratilgan). Single-subscription Stream faqat bitta obunachiga ruxsat beradi. Bitta oqimni bir nechta vidjet o'rtasida taqsimlash uchun broadcast boshqaruvchi yoki BehaviourSubject bilan rxdart paketidan foydalaning.
UI ni qayta qurish kerak bo'lgan hodisalarni filtrlash uchun buildWhen parametridan foydalaning. Shuningdek, StreamBuilder'ga uzatishdan oldin ma'lumotlarni filtrlash uchun Stream.transformer yoki Stream.where ni qo'llang.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.