从AppLifecycleState.resumed事件导航到新屏幕?

时间:2019-09-16 06:34:28

标签: flutter lockscreen

我正在尝试在AppLifecycleState事件中启动新屏幕,但是什么也没有发生。这是因为此事件中有no context available,其中将包含导航器。

每次从恢复状态(AppLifecycleState.resumed)返回时,应用程序必须打开LockScreen。最简单的情况是银行应用程序,每次打开时都受到锁屏保护。

无论代码位于何处,如何显示新屏幕?

我的无效代码:

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();
    }));
  }
}

1 个答案:

答案 0 :(得分:0)

您可以使用流来处理简历“事件”。 由于观察者位于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.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.suspending) {
      // app suspended (not used in iOS)
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey: _navigatorKey,
      ...
    );
  }

  void _showLockScreenDialog() {
    _navigatorKey.currentState.
        .pushReplacement(new MaterialPageRoute(builder: (BuildContext context) {
      return PassCodeScreen();
    }));
  }
}