有没有一种方法可以让我听Firebase onChildAdded事件并在所有屏幕上响应该事件?

时间:2020-01-31 12:49:06

标签: firebase flutter firebase-realtime-database

我遇到一个问题,我必须在应用程序的所有部分(在所有屏幕中)监听firebase添加子事件,并在添加子项时推送新的屏幕。我在所有小部件的initState()方法中监听了Firebase,并获得了相同的结果,但是我认为这不是一个好主意。有没有一种方法可以在某个地方监听Firebase事件并在触发事件时按屏幕?这是一个呼叫应用程序,因此我想显示一个屏幕,该屏幕显示触发Firebase事件时有人正在呼叫的屏幕。另外,应用程序在后台(已暂停)时应该能够显示来电屏幕。并且如果屏幕被锁定,它应该能够自动唤醒屏幕。一切都会有所帮助。

2 个答案:

答案 0 :(得分:1)

这是一个可能的解决方案,其中有一个InheritedWidget环绕您的整个应用程序,您可以向其传递当前上下文,然后随时从当前视图外部调用以触发导航或其他任何操作:

确保使用InheritedWidget包裹整个MaterialApp

return InheritedState(
  child: MaterialApp(
    body: MainView()
  ...
  )
);

然后,通过对有状态窗口小部件的didChangeDependencies方法覆盖进行调用,以确保其具有正确的上下文:

class MainView extends StatefulWidget {
  @override
  _MainViewState createState() => _MainViewState();
}

class _MainViewState extends State<MainView> {
  @override
  void didChangeDependencies() {
    InheritedState.of(this.context).loadContext(this.context);
    super.didChangeDependencies();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: RaisedButton(
        child: Text('Navigate with InheritedWidget'),
        onPressed: () {
          InheritedState.of(context).navigateAway();
        }),
    );
  }
}

class NewView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('New view from inherited widget'),),
      body: Center(
        child: Text('Test view')
      )
    );
  }
}

class InheritedState extends InheritedWidget{
  InheritedState({Key key, Widget child}) : super(key: key, child: child);
  BuildContext _buildContext;

  void loadContext(BuildContext buildContext){
    _buildContext = buildContext;
  }

  void navigateAway(){
    Navigator.of(_buildContext).push(MaterialPageRoute(
      builder: (context){
        return NewView();
      })
    );
  }

  static InheritedState of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<InheritedState>();
  }

  @override
  bool updateShouldNotify(InheritedWidget oldWidget) => true;
}

如果您拥有一个可以触发所需内容的侦听器,而不是仅调用一个方法,那么您应该可以使用相同的代码。

答案 1 :(得分:0)

尽管我使用触发器来更新内容而不是导航至另一个屏幕,但我以这种确切的方式在应用程序中使用了侦听器。我的应用程序结构合理,因此我可以从主页(不是main.dart)导航到所有其他页面,每个页面都有自己的子页面。然后,我导航回到最终的主页。因此,我只需要在主页的initState中设置侦听器,然后在注销时将其放在那里。因此,它们在所有页面中都保持活动和响应。