Flutter 从AppLifecycleState.Resume事件导航到新屏幕?
我试图在AppLifecycleState事件中启动一个新屏幕,但什么也没发生。这是因为在这个事件中有一个包含Navigator的 每次应用从恢复状态(AppLifecycleState.resume)返回时,应用必须打开锁屏。最简单的例子是银行应用程序,它在每次打开时都受到锁屏保护 如何显示新的屏幕,无论您在代码中的何处 我的代码不起作用:Flutter 从AppLifecycleState.Resume事件导航到新屏幕?,flutter,lockscreen,Flutter,Lockscreen,我试图在AppLifecycleState事件中启动一个新屏幕,但什么也没发生。这是因为在这个事件中有一个包含Navigator的 每次应用从恢复状态(AppLifecycleState.resume)返回时,应用必须打开锁屏。最简单的例子是银行应用程序,它在每次打开时都受到锁屏保护 如何显示新的屏幕,无论您在代码中的何处 我的代码不起作用: import 'package:alarm_prevozi/screens/home_screen/home_screen.dart'; import '
import 'package:alarm_prevozi/screens/home_screen/home_screen.dart';
import 'package:alarm_prevozi/screens/lock_screen/lock_screen.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:alarm_prevozi/helpers/translations.dart';
import 'package:flutter/material.dart';
void main() async {
// Then start the application
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
BuildContext myContext;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
// Listen for when the app enter in background or foreground state.
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
// user returned to our app
_showLockScreenDialog();
} else if (state == AppLifecycleState.inactive) {
// app is inactive
} else if (state == AppLifecycleState.paused) {
// user is about quit our app temporally
} else if (state == AppLifecycleState.suspending) {
// app suspended (not used in iOS)
}
}
// Main initialization
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
// Tells the system which are the supported languages
supportedLocales: translationService.supportedLocales(),
home: HomeScreen()
);
}
void _showLockScreenDialog() {
Navigator.of(context)
.pushReplacement(new MaterialPageRoute(builder: (BuildContext context) {
return PassCodeScreen();
}));
}
}
import'程序包:alarm_prevozi/screens/home_screen/home_screen.dart';
导入“包:报警/屏幕/锁屏/锁屏.省道”;
导入“package:flatter_本地化/flatter_本地化.dart”;
导入“包:alarm_prevozi/helpers/translations.dart”;
进口“包装:颤振/材料.省道”;
void main()异步{
//然后启动应用程序
runApp(MyApp());
}
类MyApp扩展了StatefulWidget{
@凌驾
_MyAppState createState()=>\u MyAppState();
}
类_MyAppState使用WidgetsBindingObserver扩展状态{
构建上下文myContext;
@凌驾
void initState(){
super.initState();
WidgetsBinding.instance.addObserver(这个);
}
@凌驾
无效处置(){
WidgetsBinding.instance.removeObserver(此);
super.dispose();
}
//监听应用程序何时进入后台或前台状态。
@凌驾
void didchangeAppifecyclestate(AppLifecycleState状态){
if(state==AppLifecycleState.resume){
//用户返回到我们的应用程序
_showLockScreenDialog();
}else if(state==AppLifecycleState.inactive){
//应用程序处于非活动状态
}else if(state==AppLifecycleState.paused){
//用户即将暂时退出我们的应用程序
}else if(state==AppLifecycleState.suspending){
//应用程序挂起(未在iOS中使用)
}
}
//主初始化
@凌驾
小部件构建(构建上下文){
返回材料PP(
本地化授权:[
GlobalMaterialAllocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
//告诉系统哪些是受支持的语言
supportedLocales:translationService.supportedLocales(),
主页:主屏幕()
);
}
void _showLockScreenDialog(){
导航器(上下文)
.pushReplacement(新材料路线)(生成器:(构建上下文){
返回密码屏幕();
}));
}
}
您可以使用流来处理恢复“事件”。
由于您的观察者位于MaterialApp之上,因此您的MyApp上下文中没有导航器,因此您需要使用GlobalKey访问MaterialApp提供的导航器
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
StreamController<bool> _showLockScreenStream = StreamController();
StreamSubscription _showLockScreenSubs;
GlobalKey<NavigatorState> _navigatorKey = GlobalKey();
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
_showLockScreenSubs = _showLockScreenStream.stream.listen((bool show){
if (mounted && show) {
_showLockScreenDialog();
}
});
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
_showLockScreenSubs?.cancel();
super.dispose();
}
// Listen for when the app enter in background or foreground state.
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
// user returned to our app, we push an event to the stream
_showLockScreenStream.add(true);
} else if (state == AppLifecycleState.inactive) {
// app is inactive
} else if (state == AppLifecycleState.paused) {
// user is about quit our app temporally
} else if (state == AppLifecycleState.detached) {
// detached from any host views
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: _navigatorKey,
...
);
}
void _showLockScreenDialog() {
_navigatorKey.currentState.
.pushReplacement(new MaterialPageRoute(builder: (BuildContext context) {
return PassCodeScreen();
}));
}
}
class\u MyAppState使用WidgetsBindingObserver扩展状态{
StreamController _showLockScreenStream=StreamController();
StreamSubscription\u showLockScreenSubs;
GlobalKey _navigatorKey=GlobalKey();
@凌驾
void initState(){
super.initState();
WidgetsBinding.instance.addObserver(这个);
_showLockScreenSubs=\u showLockScreenStream.stream.listen((bool show){
如果(已安装并显示){
_showLockScreenDialog();
}
});
}
@凌驾
无效处置(){
WidgetsBinding.instance.removeObserver(此);
_showLockScreenSubs?.cancel();
super.dispose();
}
//监听应用程序何时进入后台或前台状态。
@凌驾
void didchangeAppifecyclestate(AppLifecycleState状态){
if(state==AppLifecycleState.resume){
//用户返回到我们的应用程序,我们将事件推送到流
_showLockScreenStream.add(true);
}else if(state==AppLifecycleState.inactive){
//应用程序处于非活动状态
}else if(state==AppLifecycleState.paused){
//用户即将暂时退出我们的应用程序
}else if(state==AppLifecycleState.detached){
//与任何主体视图分离
}
}
@凌驾
小部件构建(构建上下文){
返回材料PP(
导航工作:_导航工作,
...
);
}
void _showLockScreenDialog(){
_navigatorKey.currentState。
.pushReplacement(新材料路线)(生成器:(构建上下文){
返回密码屏幕();
}));
}
}
谢谢!但这仍然会产生未处理的异常:使用不包含导航器的上下文请求的导航器操作。用于从导航器推送或弹出路由的上下文必须是导航器小部件的后代小部件的上下文。您是对的。我更新了答案。我认为这是一个使用GlobalKeys的好例子。但不建议在你的应用程序中过多地使用它们。使用GlobalKey解决方案,你几乎可以跳过StreamController部分。我把选择权留给你。