我遇到一个问题,我必须在应用程序的所有部分(在所有屏幕中)监听firebase添加子事件,并在添加子项时推送新的屏幕。我在所有小部件的initState()方法中监听了Firebase,并获得了相同的结果,但是我认为这不是一个好主意。有没有一种方法可以在某个地方监听Firebase事件并在触发事件时按屏幕?这是一个呼叫应用程序,因此我想显示一个屏幕,该屏幕显示触发Firebase事件时有人正在呼叫的屏幕。另外,应用程序在后台(已暂停)时应该能够显示来电屏幕。并且如果屏幕被锁定,它应该能够自动唤醒屏幕。一切都会有所帮助。
答案 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中设置侦听器,然后在注销时将其放在那里。因此,它们在所有页面中都保持活动和响应。