如何解决从initState导航返回对null调用了'findAncestorStateOfType'
我正在监听initState中的数据库更改(firestore)。在特定更改上,我需要将用户路由到另一个屏幕。
我的initState函数:
@override
void initState() {
super.initState();
FirebaseFirestore.instance
.collection('groups')
.where('members',arrayContains: globals.user.userId)
.limit(1)
.snapshots()
.listen((event) {
event.docs.forEach((doc) {
Navigator.of(context).pushNamedAndRemoveUntil(
'/GroupScreen',(Route<dynamic> route) => false);
});
});
}
有两种情况:
调度程序库捕获的异常方法 在null上调用了'findAncestorStateOfType'。接收者:null已尝试 调用:findAncestorStateOfType()
我不明白为什么错误仅在第二种情况下有效。
请帮助我弄清楚我在做什么错。 预先感谢。
其他信息(完整代码):
class MainScreen extends StatefulWidget {
@override
_MainScreen createState() => _MainScreen();
}
class _MainScreen extends State<MainScreen> {
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
final _scaffoldKey = new GlobalKey<ScaffoldState>();
List<String> favoritGroupsList = List<String>();
bool isLoading = true;
Stream _groupsstream;
@override
void initState() {
// Todo: implement initState
checkFirstScreen();
_groupsstream = FirebaseFirestore.instance
.collection('groups')
.where('guests',arrayContains: globals.user.userId)
.orderBy('status')
.snapshots();
if (_groupsstream != null) {
FirebaseFirestore.instance
.collection('groups')
.where('members',arrayContains: globals.user.userId)
.limit(1)
.snapshots()
.listen((event) {
event.docs.forEach((doc) {
joinUserToGroup(context,doc.id);
});
});
}
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => {
initFunctions(),Network().getAvailableFriends().then((value) => showSnackBar())
});
}
void initFunctions() async {
await Network().getAllUser();
await Network().getUser();
if (this.mounted) {
setState(() {
isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async => false,child: Scaffold(
key: _scaffoldKey,appBar: AppBar(
.
.
.
),);
}
joinUserToGroup(BuildContext context,String groupId) {
globals.tempGroup.groupId = groupId;
Navigator.of(context).pushNamedAndRemoveUntil(
'/GroupScreen',(Route<dynamic> route) => false);
_groupsstream = null;
}
}
问题出在导航器的joinUserToGroup函数中。 谢谢!
解决方法
您应该等待,直到数据可用,然后将代码放入具有Future这样的函数中
Future<viod> someFunction() async{
FirebaseFirestore.instance
.collection('groups')
.where('guests',arrayContains: globals.user.userId)
.snapshots()
.listen((event) {
event.docs.forEach((doc) {
if (doc['members'].contains(globals.user.userId)) {
SchedulerBinding.instance.addPostFrameCallback((_) {
Navigator.of(context).pushNamedAndRemoveUntil(
'/GroupScreen',(Route<dynamic> route) => false);
});
}
});
});
}
然后将函数添加到initState()
void initState() {
super.initState();
someFunction();
}
我认为这可能有用
,我发现您的问题出在BuildContext
上下文中,并且您在BuildContext
之外调用了导航器,这就是为什么会出现此错误的原因,因此您必须提供上下文,因为如果没有上下文,您将无法新屏幕,也许此链接可以帮助您The method 'findAncestorStateOfType' was called on null in flutter dart
void someFunction(BuildContext context) {
FirebaseFirestore.instance
.collection('groups')
.where('guests',(Route<dynamic> route) => false);
});
}
});
});
}
void initState() {
super.initState();
someFunction();
}
,
您是否在代码下收到诸如红线之类的错误,因为您的代码要等到 您提供像这样的代码正确的参数
joinUserToGroup(BuildContext context,String groupId) {
globals.tempGroup.groupId = groupId;
return Navigator.pushNamedAndRemoveUntil(
context,'/GroupScreen',(route) => false);
},_groupsStream = null;
}
}
我认为这是使您的应用正常运行所需要的,如果您遇到新的错误,请添加注释
,我通过在外部提供Navigator制作了您的应用,但发生同样的错误是因为您请求一个新的上下文,而该应用在MaterialApp
中创建了第一个上下文,并且在飘动中是非法的,因此您必须将通过将导航器放入从第一个上下文获取上下文的Widget
内,然后使用State Management
来更新屏幕,我认为这是唯一使用此方法的方法,如果您尝试使您的工作方式更加困难,因此您最好像Provider Package这样使用State Management Package
,这很容易理解,而对于像您这样的复杂应用,如果没有状态管理就很难制作,所以换一种方式来说,您的代码将永远无法工作,因此尝试添加更多的类并将其分离,并使用状态管理来发送数据并检查逻辑(如果您确实学习并阅读了所有内容),您将在两到四天内完成它们,而我遇到了同样的问题起初但是状态管理解决了这个问题
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。