【问题标题】:Is there a way I can listen to firebase onChildAdded Event and respond to that in all of the screens in flutter?有没有办法可以收听firebase onChildAdded 事件并在所有屏幕上响应它?
【发布时间】:2020-05-17 03:29:40
【问题描述】:

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

【问题讨论】:

  • 这是您在尝试进行 Internet 连接管理以及您可能希望在任何地方通知用户的其他情况时都会遇到的问题。您正在做的另一种方法是将当前视图的上下文发送到您的 StateManagement 解决方案或您可能正在使用的 InheritedWidget,以便它知道将新视图推送到导航器所需的上下文。
  • 我可以使用提供程序而不是继承的小部件吗?以及当应用程序在后台运行但设备被锁定时自动唤醒设备?
  • 自动唤醒设备完全不同。

标签: firebase flutter firebase-realtime-database


【解决方案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;
}

如果你有一个监听器来触发你想要的,而不仅仅是一个被调用的方法,那么你应该能够使用相同的代码。

【讨论】:

  • 我正在以应用的暂停状态收听 Firebase 事件。如果我在应用程序内执行 print(event.snapshot.value),它就可以工作。有什么办法,而不是打印,我可以弹出一个屏幕?
  • 如果您有上下文,正如我在回答中解释的那样,是的,您应该能够导航到新视图、显示对话框或任何您想要的内容。
  • 如果我暂停应用程序,即把它放在后台,上下文变为空。有什么想法可以做吗?
  • 我自己没有尝试过,但你必须有一个包来监听应用程序的简历并获取当前 Scaffold 的上下文以供使用。
  • 您知道如何在设备收到通知时自动唤醒设备吗?
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2020-12-11
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 2020-08-12
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 2011-07-14
    相关资源
    最近更新 更多