Flutter:如何在不重建的情况下接收新数据和更新 Widget
Flutter: How to receive new Data and update Widget without rebuildung
我目前正面临一个烦人的设计问题,我认为这是我自己造成的,并且会颤动 :D
在我的小部件中,我使用 FutureBuilder。创建小部件后,它会获取初始数据 - 一切都很好。
现在我得到了一个 WebSocket 连接,它向我发送更新的数据。我将这些数据传递给我的小部件,现在我面临的问题是我更改了数据并且小部件没有重新加载或者我另外使用 setState 并且小部件将自行更新并再次获取新数据,因为它正在重建并且 futurebuilder 开始发挥作用再次。
那根本没有效率。
我怎样才能防止这种行为。
我想,我的结构可能不适合这种颤动行为,因此我可能必须首先在小部件外部加载数据,通过构造函数传递 em 并在我的小部件内设置一个侦听器以获取 WebSocket 通知然后调用 setState... 对吗?
这是一个简短的示例,它确实重建并因此再次自行获取数据 -> 所以不是我想要的解决方案:
class _ExampleState extends State<Example> {
Stream wsData;
_ExampleState() {
wsData.listen((event) {
setState(() {
//update data
});
});
}
_getData() {
// Call network manager and fetch data
return {'fetchedData': 'data'};
}
@override
Widget build(BuildContext context) {
return Container(
child: FutureBuilder(
future: _getData(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data != null) {
Text('data arrived: ' + snapshot.data.toString());
} else {
return CircularProgressIndicator();
}
}),
);
}
}
如果您有一个不断自我更新的数据源,您可以使用 StreamBuilder 而不是 FutureBuilder。 StreamBuilder 侦听数据源并在每次从中获取更新后重建小部件。
我的解决方案:
在我的用例中,它不适用于 Streambuilder。在新数据来自流后传递到 Widget 的数据不知何故是相同的。
现在我正在使用 FutureBuilder 获取初始数据并将流传递到我的小部件。 Widget 监听 Stream 上的变化并自行更新..
此外,就像@Rémi Rousselet 提到的那样,我在 initState 方法中启动提取过程并将其分配给本地未来变量,而不是直接使用 FutureBuilder 触发提取.
最近我也遇到了这个问题,我用 setState 从另一个 class 传递数据。数据最初是使用 initState 更新的,然后我使用局部变量更改了该特定数据,但是当新数据从父 class 到达时,这并没有更新。
后来我找到了didUpdateWidget
方法
@override
void didUpdateWidget(covariant ExampleClass oldWidget) {
print("didUpdateWidget: ${widget.value}");
selectedIndex = widget.value.toInt().toString(); //local variable
list.clear(); // list with data
_buildList(); // list will rebuild with new data
super.didUpdateWidget(oldWidget);
}
基本上在 stateful class 中使用这个 override 方法 class 我们可以在小部件发生变化时做一些事情.
现在我可以使用局部变量和父变量更新数据了。
我目前正面临一个烦人的设计问题,我认为这是我自己造成的,并且会颤动 :D
在我的小部件中,我使用 FutureBuilder。创建小部件后,它会获取初始数据 - 一切都很好。 现在我得到了一个 WebSocket 连接,它向我发送更新的数据。我将这些数据传递给我的小部件,现在我面临的问题是我更改了数据并且小部件没有重新加载或者我另外使用 setState 并且小部件将自行更新并再次获取新数据,因为它正在重建并且 futurebuilder 开始发挥作用再次。 那根本没有效率。 我怎样才能防止这种行为。
我想,我的结构可能不适合这种颤动行为,因此我可能必须首先在小部件外部加载数据,通过构造函数传递 em 并在我的小部件内设置一个侦听器以获取 WebSocket 通知然后调用 setState... 对吗?
这是一个简短的示例,它确实重建并因此再次自行获取数据 -> 所以不是我想要的解决方案:
class _ExampleState extends State<Example> {
Stream wsData;
_ExampleState() {
wsData.listen((event) {
setState(() {
//update data
});
});
}
_getData() {
// Call network manager and fetch data
return {'fetchedData': 'data'};
}
@override
Widget build(BuildContext context) {
return Container(
child: FutureBuilder(
future: _getData(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data != null) {
Text('data arrived: ' + snapshot.data.toString());
} else {
return CircularProgressIndicator();
}
}),
);
}
}
如果您有一个不断自我更新的数据源,您可以使用 StreamBuilder 而不是 FutureBuilder。 StreamBuilder 侦听数据源并在每次从中获取更新后重建小部件。
我的解决方案: 在我的用例中,它不适用于 Streambuilder。在新数据来自流后传递到 Widget 的数据不知何故是相同的。 现在我正在使用 FutureBuilder 获取初始数据并将流传递到我的小部件。 Widget 监听 Stream 上的变化并自行更新..
此外,就像@Rémi Rousselet 提到的那样,我在 initState 方法中启动提取过程并将其分配给本地未来变量,而不是直接使用 FutureBuilder 触发提取.
最近我也遇到了这个问题,我用 setState 从另一个 class 传递数据。数据最初是使用 initState 更新的,然后我使用局部变量更改了该特定数据,但是当新数据从父 class 到达时,这并没有更新。
后来我找到了didUpdateWidget
方法
@override
void didUpdateWidget(covariant ExampleClass oldWidget) {
print("didUpdateWidget: ${widget.value}");
selectedIndex = widget.value.toInt().toString(); //local variable
list.clear(); // list with data
_buildList(); // list will rebuild with new data
super.didUpdateWidget(oldWidget);
}
基本上在 stateful class 中使用这个 override 方法 class 我们可以在小部件发生变化时做一些事情.
现在我可以使用局部变量和父变量更新数据了。