Dmitry Bubnenkov
Dmitry Bubnenkov

Reputation: 9859

How can I rerend data from Stream in Stateless Widget?

I am trying to re-rend Stateless widget every time when I am getting new data from Stream. But it does not work, and I can't understand when I should to call re-rend function:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';


Stream<int> stream; // I maked it's global for simplification
void main() 
{
  MyClass myClass = MyClass();

  WidgetsFlutterBinding.ensureInitialized();  
  SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft])
      .then((_) {
    runApp(new MyApp());
  });
}

class MyClass
{
  MyClass()
  {
    stream = Stream<int>.periodic(Duration(seconds: 1), (t) => t+1).take(9);
    print("hello");
  }
}

class MyApp extends StatelessWidget
{
  @override
  Widget build(BuildContext context)
  {
    return MaterialApp(
      title: "Hello",
      routes: {
        '/' : (context) => SplashScreen(),
      }

    );
  }
}

class SplashScreen extends StatelessWidget {

  @override
  Widget build(BuildContext context)
  {
    return Scaffold(
      appBar: AppBar(), 
      body: Container(
        child: Text("Hello World, $stream"),
      ),
    );
  }

}

Upvotes: 0

Views: 529

Answers (1)

chunhunghan
chunhunghan

Reputation: 54367

please check example below
Both Parent and Child Widget are Stateless.
Use simple class to wrap stream controller, here class name is bloc
Child widget use StreamBuider
In parent widget call bloc function and pass parameter and then child widget will render

code snippet

bloc.changeState(true)

...
class Bloc {
  final _fileController = StreamController<bool>();

  changeState(bool val) {
    _fileController.sink.add(val);
  }

  get hasFile => _fileController.stream;

  dispose() {
    _fileController.close();
  }
}

full code

import 'package:flutter/material.dart';
import 'dart:async';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Homepage(),
    );
  }
}

class Homepage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        actions: <Widget>[
          FlatButton(
              child: Text('addFile'),
              onPressed: () {
                bloc.changeState(true);
              }),
          FlatButton(
              child: Text('deleteFile'),
              onPressed: () {
                bloc.changeState(false);
              })
        ],
      ),
      body: Child(),
    );
  }
}

class Child extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
      stream: bloc.hasFile,
      initialData: false,
      builder: (context, snapshot) {
        return snapshot.data ? Text('has a file') : Text("no File");
      },
    );
  }
}


class Bloc {
  final _fileController = StreamController<bool>();

  changeState(bool val) {
    _fileController.sink.add(val);
  }

  get hasFile => _fileController.stream;

  dispose() {
    _fileController.close();
  }
}

final bloc = Bloc();

enter image description here

Upvotes: 1

Related Questions