由于flutter在不同的条件下多次调用build方法,因此为了避免多次获取数据,我在initState中初始化了数据。
我想在数据准备好后重新构建窗口小部件。
这是我的代码:
class Test extends StatefulWidget {
@override
_TestState createState() => new _TestState();
}
class _TestState extends State<Test> {
Data data;
bool dataReady = false;
@override
void initState() {
super.initState();
getData(context).then((Data data) async {
setState(() {
dataReady= true;
});
});
}
@override
Widget build(BuildContext context) {
if (dataReady) {
return createMainContent(context);
} else {
return new Container();
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,它导致以下异常:在_TestState.initState()完成之前调用了InheritFromWidgetOfExactType(_InheritedProvider)或InheritFromElement()。
我可以知道我在这里做错什么吗?
当我将以下行添加到getData(context)的实现中时
await Future.delayed(new Duration(milliseconds: 300));
Run Code Online (Sandbox Code Playgroud)
,不会发生例外。
谢谢!
Jav*_*ana 18
对于以后来这里的每个人
最好使用类的@override void didChangeDependencies ()方法State。
从文档
这个方法也会在 initState 之后立即调用。从此方法调用 BuildContext.inheritFromWidgetOfExactType 是安全的。
但请务必检查您是否已经执行了初始化
@override
void didChangeDependencies() {
super.didChangeDependencies();
if (bloc == null) { // or else you end up creating multiple instances in this case.
bloc = BlocProvider<MyBloc>.of(context);
}
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*cel 12
编辑:下面更好的答案。
显然,您无法访问getData(context)期间initState(更具体地说:在完成之前)。
我相信,原因是它getData试图InheritedWidget在树中查找祖先,但树刚刚被构建(您的小部件是在父小部件的 期间创建的build)。
显而易见的解决方案是将getData的查找延迟到稍后的时间点。有几种方法可以实现:
scheduleMicrotask应该工作正常。在第一次build通话时查看它。您可以将一个isInitialized字段设置为falseand in you build,例如:
if (!isInitialized) {
isInitialized = true;
// TODO: do the getData(...) stuff
}
Run Code Online (Sandbox Code Playgroud)另一种方法是将其放在和PostFrameCallback之间。initStateBuild
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) => getData());
super.initState();
}
getData() async {
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2122 次 |
| 最近记录: |