StreamProvider未更新状态

时间:2019-08-05 19:48:27

标签: flutter dart flutter-provider

我正在尝试使用StreamProvider(来自this的超棒软件包),但是我一直在努力使特定的流工作。

我创建了一个StreamController,用于通过其Stream向其Sink添加数据。所有这些似乎都工作正常。但是,当将此StreamStreamProvider一起使用时,小部件树不会反映Stream的更改。但是,使用StreamBuilder确实可以正常工作。

使用StreamProvider的代码:

class TestPage extends StatelessWidget {
  final Mockup exchange = ExchangeApi.mockup;

  @override
  Widget build(BuildContext context) {
    return StreamProvider<List<Data>>(
      builder: (BuildContext context) => Wrapper.mockup.stream,
      initialData: null,
      catchError: (BuildContext context, e) {
        print("Error: $e");
        return null;
      },
      child: TestPageBody(),
    );
  }
}

class TestPageBody extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    List<Data> dataList = Provider.of<List<Data>>(context);
    return ListView.builder(
      itemCount: dataList?.length ?? 0,
      itemBuilder: (BuildContext context, int index) {
        return Text(dataList[index].name);
      },
    );
  }
}

我一直在寻找为什么这行不通,但是还没有找到答案。但是我确实找到了一些东西:

  • 使用Flutter Desktop Embedding,当窗口调整大小时(因此强制重建),UI确实反映了流中的更改。使用热刷新时会看到相同的效果。
  • 流中不断添加新数据,我通过调试并简单地打印出数据来对其进行测试

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:3)

大多数提供程序(不包括\n)的默认行为是假定传递的值是不可变的。

这样,如果您的流发出的值与先前发出的值相同,则不会重建依赖项。

有两种解决方案:

  • 使流发出的值不可变,以便正确执行ChangeNotifierProvider

  • 覆盖previousValue == newValue,以便在值不变时不过滤值。

    一个简单的updateShouldNotify就可以了。


在理想世界中,更喜欢不变性。

这可以通过在将对象发送到updateShouldNotify: (_, __) => true之前制作对象的副本来完成:

streamController.add(value)

第二个(可选)步骤是覆盖List<T> value; streamController.add(List.from(value)); (或对象上的updateShouldNotify),以通知提供者该值没有更改。

使用operator==,可以使用List中的ListEquality

collection/collection.dart