如何在无状态小组件中重播Stream中的数据?

时间:2019-09-17 14:18:54

标签: flutter

每次从Stream获取新数据时,我都试图重新渲染无状态小部件。但这是行不通的,我不知道何时应该调用re-rend函数:

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"),
      ),
    );
  }

}

1 个答案:

答案 0 :(得分:1)

请在下面查看示例
父级和子级小部件均为无状态。
使用简单的类包装流控制器,这里的类名为bloc
子小部件使用StreamBuider
在父窗口小部件中调用bloc函数并传递参数,然后子窗口小部件将呈现

代码段

bloc.changeState(true)

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

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

  get hasFile => _fileController.stream;

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

完整代码

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