我正在尝试使用StreamProvider
(来自this的超棒软件包),但是我一直在努力使特定的流工作。
我创建了一个StreamController
,用于通过其Stream
向其Sink
添加数据。所有这些似乎都工作正常。但是,当将此Stream
与StreamProvider
一起使用时,小部件树不会反映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);
},
);
}
}
我一直在寻找为什么这行不通,但是还没有找到答案。但是我确实找到了一些东西:
任何帮助将不胜感激!
答案 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