Flutter Stream Builder (part - 1)

Share

ဒီ blog မှာတော့ Flutter ရဲ့ Stream Builder ကိုစတင်လေ့လာသွားကြပါမယ်။ Stream က နောက်ပိုင်း app တွေရေးတဲ့ အခါ တော်တော်လေး မရှိမဖြစ်လို့ အသုံးဝင်ပါတယ်။ Stream Builder ကို သုံးပြီး demo သေးသေးလေးရေးကြည့်ပါမယ်။

Stream Builder


Stream Builder က Widget တစ်ခုပါပဲ။ Flutter ရဲ့ ထုံးစံအတိုင်း everything is widget ပါ။ Stream Builder ကို argument နှစ်ခု pass ပေးရပါတယ်။ Stream တစ်ခု နဲ့ builder တစ်ခုပါ။ builder က stream ထဲက လာတဲ့ ကောင်တွေကို widget ပြောင်းပေးတာပါ။

Stream ကို ဥပမာပေးရရင် ပိုက် တစ်လုံးနဲ့ တူပါတယ်။ တစ်ဖက်က ဝင်လာတဲ့ ကောင်ကို တခြားတစ်ဖက်ကနေထိုင်စောင့်နေတဲ့ သဘောမျိုးပါ။ စက်ရုံတွေမှာ ပစ္စည်းတွေတန်းစီ ထွက်လာတာကို အလုပ်သမားက ပါကင်ပိတ်နေတဲ့ ပုံစံနဲ့ လဲ တူပါတယ်။ Stream တစ်ခု build ပြီး အဲထဲကို တစ်ခုခု sink လုပ်ပေးလိုက်လို့ရပါတယ်။ Stream တစ်ခုမှာ multiple listeners တွေလဲ ရှိနိုင်ပါတယ်။ ကျွန်တော်တို့ မြင်သာအောင် စရေးကြည့်ရအောင်

စစချင်းမှာ loading လည်နေပြီး button click မှ image တွေတစ်ခု ချင်းစီကို ပြတဲ့ mini demo လေးရေးကြည့်ပါမယ်။

image

Code Implementation

stream_builder.dart
  final imageStream = StreamController<Image>();

Stream Controller တစ်ခု တည်ဆောက်ရပါမယ်။

image

Slide Image button ကို click လိုက်တာနဲ့ loading ကို remove ပြီး stream ထဲကို ပုံတွေ sink လုပ်ပြီး ထည့်မှာပါ။

Stream Builder Widget တစ်ခု စဆောက်ပါမယ်

stream_builder.dart
 StreamBuilder(
        stream: imageStream.stream,
        builder:
            (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
              if (!snapshot.hasData) {
                return CircularProgressIndicator(
                  backgroundColor: Colors.white,
                  strokeWidth: 3,
                  valueColor:
                      new AlwaysStoppedAnimation<Color>(Colors.black),
                    );
                  }

              if (snapshot.connectionState == ConnectionState.done) {}
              return Container(
                height: 220,
                width: 220,
                decoration: BoxDecoration(
                    borderRadius: BorderRadius.all(Radius.circular(10)),
                ),
                child: ClipRRect(
                      borderRadius: BorderRadius.all(Radius.circular(10)),
                      child: snapshot.data,
                    ),
                  );
                }),

ဒါက button click တိုင်းမှာ stream ထဲကို ပုံတွေ sink လုပ်မှာပါ

stream_builder.dart
  if (imageCounter < imageList.length) {
        imageStream.sink.add(imageList[imageCounter]);
        } else {
      imageStream.close();
    }

image List တစ်ခုကတော့ ကိုယ့်ဘာသာဆောက်ထားဖို့ လိုပါလိမ့်မယ်။

Code File


code ဖတ်ကြည့်ရင်တော့ နားလည်လွယ်မယ်ထင်ပါတယ်။
stream_builder.dart
import 'dart:async';

import 'package:flutter/material.dart';

class FLutterStreamBuilder extends StatefulWidget {
  
  _FLutterStreamBuilderState createState() => _FLutterStreamBuilderState();
}

class _FLutterStreamBuilderState extends State<FLutterStreamBuilder> {
  final imageStream = StreamController<Image>();
  int imageCounter = -1;

  double _height;
  double _width;

  final List<Image> imageList = [
    Image.asset(
      'assets/images/image-one.jpg',
      fit: BoxFit.cover,
    ),
    Image.asset(
      'assets/images/image-two.jpeg',
      fit: BoxFit.cover,
    ),
    Image.asset(
      'assets/images/image-three.jpeg',
      fit: BoxFit.cover,
    ),
    Image.asset(
      'assets/images/image-four.jpeg',
      fit: BoxFit.cover,
    ),
  ];

  
  void dispose() {
    imageStream.close();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    _height = MediaQuery.of(context).size.height;
    _width = MediaQuery.of(context).size.width;
    return Scaffold(
      body: Container(
        height: _height,
        width: _width,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            StreamBuilder(
                stream: imageStream.stream,
                builder:
                    (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
                  if (!snapshot.hasData) {
                    return CircularProgressIndicator(
                      backgroundColor: Colors.white,
                      strokeWidth: 3,
                      valueColor:
                          new AlwaysStoppedAnimation<Color>(Colors.black),
                    );
                  }

                  if (snapshot.connectionState == ConnectionState.done) {}
                  return Container(
                    height: 220,
                    width: 220,
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.all(Radius.circular(10)),
                    ),
                    //  color: snapshot.data,
                    child: ClipRRect(
                      borderRadius: BorderRadius.all(Radius.circular(10)),
                      child: snapshot.data,
                    ),
                  );
                }),
            RaisedButton(
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(30)),
              color: Colors.black,
              onPressed: () {
                imageCounter++;

                if (imageCounter < imageList.length) {
                  imageStream.sink.add(imageList[imageCounter]);
                } else {
                  imageStream.close();
                }
              },
              textColor: Colors.white,
              child: Text(
                "Slide image".toUpperCase(),
                style: TextStyle(
                    fontSize: 14,
                    fontWeight: FontWeight.w600,
                    letterSpacing: 1),
              ),
            )
          ],
        ),
      ),
    );
  }
}


Stream ကိုတော့ dispose ပြန်လုပ်ပေးဖို့ လိုပါတယ်။ မလုပ်ပေးရင် stream က တောက်လျှောက် run နေပြီး memory နဲ့ ပတ်သတ်ပြီး ပြသနာရှိလာနိုင်ပါတယ်။

ဒါက stream အစပဲရှိပါသေးတယ်။

နောက် blog တွေမှာ stream boardcasting အကြောင်းတွေ ထပ်ရေးပါဦးမယ်

blog တင်တိုင်း သိချင်တယ်ဆိုရင် subscribe လုပ်သွားပေးပါ ကျေးဇူးပါ

Subscribe