我想创建一个加载器数据,最后,屏幕加载的数据将自动更改屏幕(使用Navigator)。
但是我有一些问题。
Unhandled Exception: NoSuchMethodError: The method 'ancestorStateOfType' was called on null.
在方法“ getDataOfUser()”的末尾,“ print(a)”执行得很好,但是当它尝试更改屏幕时它崩溃了,我遇到了这个错误:
E/flutter (32148): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: NoSuchMethodError: The method 'ancestorStateOfType' was called on null.
E/flutter (32148): Receiver: null
E/flutter (32148): Tried calling: ancestorStateOfType(Instance of 'TypeMatcher<NavigatorState>')
E/flutter (32148): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:50:5)
E/flutter (32148): #1 Navigator.of (package:flutter/src/widgets/navigator.dart:1446:19)
E/flutter (32148): #2 LoginScreenPresenter.initState.<anonymous closure> (package:test_app/login_presenter.dart:35:17)
class loginPresenter extends StatefulWidget {
Vendeur v;
loginPresenter({Key key, this.v}) : super(key: key);
@override
LoginScreenPresenter createState() => new LoginScreenPresenter();
}
class LoginScreenPresenter extends State<loginPresenter> {
RestDatasource api = new RestDatasource();
BuildContext context;
bool finish = false;
@override
void initState() {
getDataOfUser(widget.v).then((a) {
print(a)
Navigator.of(context).pushReplacement(new MaterialPageRoute(
builder: (BuildContext context) => HomePage(
v: widget.v,
)));
});
super.initState();
}
Future<bool> getDataOfUser(Vendeur user) async {
await api.getRegionsFromUser(user.idV).then((list) async {
if (list != null) {
for (var i = 0; i < list.length; ++i) {
await DBProvider.db.newRegion(list[i], 1);
}
}
});
await api.getClientsFromUser(user.idV).then((list) async {
if (list != null) {
for (var i = 0; i < list.length; ++i) {
await DBProvider.db.newClient(list[i], 1);
}
}
});
await api.getInterlocuteursFromUser(user.idV).then((list) async {
if (list != null) {
for (var i = 0; i < list.length; ++i) {
await DBProvider.db.newInterlocuteurs(list[i], 1);
}
}
});
await api.getVisitesFromUser(user.idV).then((list) async {
if (list != null) {
for (var i = 0; i < list.length; ++i) {
await DBProvider.db.newVisite(list[i], 1);
}
}
});
await api.getAvoirsFromUser(user.idV).then((list) async {
if (list != null) {
for (var i = 0; i < list.length; ++i) {
if (list[i].deleted == 0) {
await DBProvider.db.newAvoir(list[i], 1);
}
}
}
});
await api.getRapportsFromUser(user.idV).then((list) async {
if (list != null) {
for (var i = 0; i < list.length; ++i) {
await DBProvider.db.newRapport(list[i], user);
}
}
});
return true;
}
@override
Widget build(context) {
return RaisedButton(
onPressed: () {
Navigator.push(
context,
SlideRightRoute(
widget: HomePage(
v: widget.v,
)));
},
child: Text('go'),
);
}
}
答案 0 :(得分:3)
我遇到了这个问题,我检查了mounted
,现在一切正常。
{...
if(!mounted) return;
Navigator.of(context).pop();
...}
答案 1 :(得分:0)
您的context
从未分配。您正在使用仍为空的上下文调用Navigator。构建时,尝试从页面中为其分配上下文。
@override
Widget build(context) {
setState(() => this.context = context);
...
}
答案 2 :(得分:0)
如果您在执行操作时尝试实现加载对话框,请注意,如果对话框没有时间进行实际构建,则会引发此错误。
以下示例可能会失败,因为showLoadingDialog
及其对应的pop
之间没有延迟,因此context
没有时间存在于{{1 }}:
showLoadingDialog
但是,延迟///DON'T DO THIS
final GlobalKey<State> _loadingKey = GlobalKey<State>();
ListTile(
leading: Text("Sign Out"),
onTap: () async {
showLoadingDialog(context, _loadingKey);
Navigator.of(_loadingKey.currentContext, rootNavigator: true)
.pop();
},
),
的构建应该可以使showLoadingDialog
正常工作而不会显示错误:
pop
我不建议您在代码中添加/// This works without error
final GlobalKey<State> _loadingKey = GlobalKey<State>();
ListTile(
leading: Text("Sign Out"),
onTap: () async {
showLoadingDialog(context, _loadingKey);
await Future.delayed(Duration(seconds: 2));
Navigator.of(_loadingKey.currentContext, rootNavigator: true)
.pop();
},
),
语句以使您的对话框正常工作,但最初我不知道为什么某些await Future.delayed...
可以正常工作,而有些却无法正常工作没错-希望这可以指导某人更快地解决问题。
答案 3 :(得分:0)
我正在使用全局状态变量
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
我试图使用下面的代码行弹出上下文
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
由于我的代码有许多嵌套循环,因此该代码给了我错误。我改用下面的代码来修复此错误消息
Navigator.of(context, rootNavigator: true).pop();
有时会发现在嵌套循环中,使用全局状态变量时上下文设置不正确,并且可能导致出现此错误消息。