微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从initState导航返回对null调用了'findAncestorStateOfType'

如何解决从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);
      });
    });
  }

两种情况

  1. 一个数据库更改在用户打开应用前之前生效。然后,当用户打开应用程序时,他会直接路由到另一个屏幕,没有问题
  2. 另一方面,当应用程序打开且数据库更改生效时,用户重定向到另一个屏幕,并出现上述错误

调度程序库捕获的异常方法 在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 举报,一经查实,本站将立刻删除。