首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >StreamBuilder没有在里面重新渲染小部件吗?

问StreamBuilder没有在里面重新渲染小部件吗?
EN

Stack Overflow用户
提问于 2019-04-02 17:03:40
回答 2查看 3.6K关注 0票数 3

我创建了这个代码,我想要发生的是,当我按下按钮时,我希望piechart重新呈现为新值(应该是旧值,但食品值增加了1)我使用的是pie_chart: 0.8.0包中的piechart。存放只是一个pojo (字符串类别和整型存放) bloc.dart包含块的全局实例,流的getter和类型流的初始化以下是我的代码:

代码语言:javascript
复制
import 'package:flutter/material.dart';
import 'package:pie_chart/pie_chart.dart';
import 'bloc.dart';
import 'Deposit.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'bloc Chart',
      theme: ThemeData(
        primarySwatch: Colors.blueGrey,
      ),
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  Map<String, double> datamap = new Map();

  @override
  Widget build(BuildContext context) {
    datamap.putIfAbsent("Food", () => 5);
    datamap.putIfAbsent("transportation", () => 3);
    return Scaffold(
      appBar: AppBar(
        title: Text("PieChart using blocs"),
      ),
      body: Column(
        children: <Widget>[
          StreamBuilder<Deposit>(
              stream: bloc.data, //A stream of Deposit data
              builder: (context, snapshot) {
                addDeposit(Deposit("Food", 1), datamap);
                debugPrint("Value of food in map is: ${datamap["Food"]}");
                return PieChart(dataMap: datamap);
              }),
          SizedBox.fromSize(
            size: Size(20, 10),
          ),
          RaisedButton(
            onPressed: () {
              bloc.add(Deposit("Food", 1)); //returns the stream.add
            },
            child: Icon(Icons.add),
          ),
        ],
      ),
    );
  }

  void addDeposit(Deposit dep, Map<String, double> map) {
    if (map.containsKey(dep.category)) {
      map.update(dep.category, (value) => value + dep.price);
    } else
      map.putIfAbsent(dep.category, () => dep.price);
  }
}
EN

回答 2

Stack Overflow用户

发布于 2019-04-02 18:14:55

我认为你的问题是流不会触发新的事件。您不必关闭流即可进行重建。我在您的代码中看不到您正在为流触发新事件的任何地方。查看下面的代码,了解如何使用StreamBuilder更新StatelessWidget的简单方法。

代码语言:javascript
复制
class CustomWidgetWithStream extends StatelessWidget {
  final CustomBlock block = CustomBlock();

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        StreamBuilder(
            stream: block.stream,
            builder: (context, stream) {
              return Text("${stream.data.toString()}");
            }),
        RaisedButton(
          onPressed: () {
            block.incrementNumber();
          },
          child: Text("Increment"),
        )
      ],
    );
  }
}

class CustomBlock {
  num counter = 10;
  final StreamController<num> _controller = StreamController();

  Stream<num> get stream => _controller.stream;

  CustomBlock() {
    _controller.onListen = () {
      _controller.add(counter); // triggered when the first subscriber is added
    };
  }

  void incrementNumber() {
    counter += 1;
    _controller.add(counter); // ADD NEW EVENT TO THE STREAM
  }

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

虽然这是一个有效的代码片段,但我强烈建议您将小部件从StatelessWidget更改为StatefulWidget,原因有两个:*如果您“照本宣科”,如果小部件自己更改内容,那么它就不是StatelessWidget,无状态小部件只显示提供给它的数据。在您的示例中,小部件负责处理点击,然后决定下一步做什么以及如何更新自身。*如果您正在使用流,在有状态窗口小部件中,您可以安全地关闭流,正如您在上面的代码中所看到的,没有安全的方法来关闭流。如果你不关闭流,可能会有不必要的行为,甚至崩溃。

票数 1
EN

Stack Overflow用户

发布于 2019-04-03 01:05:39

这是我的区块文件

代码语言:javascript
复制
import 'package:rxdart/rxdart.dart';
import 'package:testing/Deposit.dart';

class Bloc{

  final _data = new BehaviorSubject<Deposit>();

  Stream<Deposit> get data => _data.stream;

  Function(Deposit) get add => _data.sink.add;

  void dispose(){
    _data.close();
  }

}

Bloc bloc = new Bloc();
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55470815

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档