flutterstreamasyncMenengah3 mnt baca

StreamBuilder: Mendengarkan Aliran Data

Tangani data yang datang berkali-kali seperti posisi realtime atau chat dengan StreamBuilder.

Future vs Stream

Future menghasilkan satu nilai di masa depan (contoh: respons API). Stream menghasilkan banyak nilai sepanjang waktu (contoh: pesan chat masuk, harga saham realtime, status koneksi). StreamBuilder adalah padanan FutureBuilder untuk stream.

Membuat dan mendengarkan stream

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

  @override
  State<HargaSaham> createState() => _HargaSahamState();
}

class _HargaSahamState extends State<HargaSaham> {
  late final Stream<int> _streamHarga;

  @override
  void initState() {
    super.initState();
    _streamHarga = Stream.periodic(
      const Duration(seconds: 1),
      (i) => 10000 + (i * 137) % 500,
    );
  }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<int>(
      stream: _streamHarga,
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Text('Menunggu data...');
        }
        if (snapshot.hasError) {
          return Text('Error: ${snapshot.error}');
        }
        return Text(
          'Harga: Rp${snapshot.data ?? 0}',
          style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
        );
      },
    );
  }
}

Setiap detik stream mengirim angka baru dan builder dipanggil ulang otomatis.

initialData: hindari kedip loading

Untuk stream yang langsung punya nilai awal, beri initialData agar UI tidak menampilkan loading sesaat:

dart
StreamBuilder<bool>(
  stream: koneksiStream,
  initialData: true,
  builder: (context, snapshot) {
    final online = snapshot.data ?? true;
    return Icon(
      online ? Icons.wifi : Icons.wifi_off,
      color: online ? Colors.green : Colors.red,
    );
  },
)

Kapan StreamBuilder kurang cukup?

StreamBuilder bagus untuk satu stream di satu widget. Tapi kalau banyak widget butuh stream yang sama, atau stream perlu diolah (filter, combine, debounce), pindahkan logika ke state management seperti Riverpod StreamProvider atau BLoC. Widget sebaiknya hanya menampilkan, bukan mengatur stream yang kompleks.

Catatan teknis: Stream single-subscription hanya bisa didengarkan sekali. Kalau dua StreamBuilder mendengarkan stream yang sama, yang kedua akan error "Stream has already been listened to". Solusinya: ubah menjadi broadcast stream dengan .asBroadcastStream(), atau bagikan lewat provider yang mengelola satu subscription. Juga, StreamBuilder otomatis membatalkan subscription saat di-dispose, jadi tidak perlu cancel manual kecuali kamu subscribe sendiri di initState.