我很难尝试根据子视图“事件”来更新视图的一部分...让我解释一下:
我有一个由Scaffold
组成的屏幕,其中有一个自定义窗口小部件,它作为body
,该窗口小部件调用rest api来获取要显示的数据(它使用了{{3} }),然后分派一个FutureBuilder(基本上包裹了Flutter的Notification)来更新floatingActionButton
(至少在我看来:P)。 >
这是屏幕的build
方法:
@override
Widget build(BuildContext context) {
return NotificationListener<MyNotification>(
onNotification: onMyNotification,
child: Scaffold(
appBar: MyAppBar(),
body: MyRemoteObjectView(),
floatingActionButton: MyFloatingButton(),
),
);
}
该视图完美呈现,从服务器检索数据并由MyRemoteObjectView
显示,并且成功分派和接收了通知,但是一旦我在回调中调用setState()
,我就会得到例外:
在构建过程中调用setState()或markNeedsBuild()。
这是回调(在上面的build
方法的同一类中定义):
bool onMyNotification(MyNotification notification) {
AsyncSnapshot snapshot = notification.snapshot;
if (snapshot.connectionState == ConnectionState.done) {
setState(() {
// these flags are used to customize the appearance and behavior of the floating button
_serverHasBeenCalled = true;
_modelDataRetrieved = snapshot.hasData;
});
}
return true;
}
这是我发送通知的地方(MyRemoteObjectView
状态的构建方法):
@override
Widget build(BuildContext context) {
return FutureBuilder<T>(
future: getData(),
builder: (BuildContext context, AsyncSnapshot<T> snapshot) {
MyNotification(snapshot).dispatch(context);
// ...
关键是:我应该告诉Flutter重画浮动按钮(和/或其他小部件)的方式是如何和何时? (因为当然没有setState
,我没有例外,但是按钮没有刷新)
我把整个事情弄错了吗?有更简单的方法吗?让我知道
答案 0 :(得分:1)
FutureBuilder 生成后,它会等待将来返回值。完成后,您将调用 setState ,然后将再次构建 FutureBuilder ,依此类推,从而导致无限的重画循环。
您确定在这种情况下需要FutureBuilder和NotificationListener吗?您应该像这样在StatefulWidget的 initState 中执行此操作:
@override
void initState() {
super.initState();
getData().then((data) {
setState(() {
_serverHasBeenCalled = true;
_modelDataRetrieved = true;
});
});
}
您还可以将 Future 存放在一个状态中,并将其传递给 FutureBuilder 。