首页 > 解决方案 > 有没有办法在 Flutter 中重新绘制屏幕或导航到 AppLifecycleState.paused 上的不同屏幕

问题描述

我有一个包含敏感媒体信息的 Flutter 应用程序,企业希望在将应用程序放入后台时隐藏此信息,包括“最近使用的应用程序”屏幕。

我已经添加了 WidgetsBindingObserver 并且正在正确监听事件。恢复状态正确触发并将用户发送回登录页面;但是,paused 事件在收到状态时不会做任何事情。作为参考,我尝试将一个新屏幕推送到堆栈上,并弹出所有屏幕直到登录,但都不起作用。

@override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    switch (state) {
      case AppLifecycleState.paused:
        Navigator.of(context).push(new PageRouteBuilder(
          pageBuilder: (_, __, ___) => new Splash(
                inBackground: true,
              ),
        ));
        break;
      case AppLifecycleState.resumed:
        Navigator.of(context).pushNamed('/login');
        break;
      default:
        break;
    }
  }

我希望在收到暂停事件时能够更改屏幕以保护此敏感信息。欢迎任何想法!

编辑:最新的代码。

import 'package:boxview_mobile_flutter/screens/splash/index.dart';
import 'package:boxview_mobile_flutter/services/shared_prefs.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';

class PushNotifications extends StatefulWidget {
  @override
  _PushNotificationsState createState() => _PushNotificationsState();
}

class _PushNotificationsState extends State<PushNotifications> with WidgetsBindingObserver {
  bool loggedOut = false;
  final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();

  @override
  Widget build(BuildContext context) {
    return Container(child: Splash(loggedOut: this.loggedOut));
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    switch (state) {
      case AppLifecycleState.paused:
        print("Paused");
        break;
      case AppLifecycleState.inactive:
        print("inactive");
        setState(() {
          loggedOut = true;
        });
        break;
      case AppLifecycleState.suspending:
        print("suspending");
        break;
      case AppLifecycleState.resumed:
        setState(() {
          loggedOut = false;
        });
        print("resumed");
        break;
    }
  }

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    _firebaseMessaging.configure(
      onMessage: (Map<String, dynamic> message) async {
        print("onMessage: $message");
      },
      onLaunch: (Map<String, dynamic> message) async {
        print("onLaunch: $message");
      },
      onResume: (Map<String, dynamic> message) async {
        print("onResume: $message");
      },
    );
    _firebaseMessaging.requestNotificationPermissions(const IosNotificationSettings(sound: true, badge: true, alert: true));
    _firebaseMessaging.onIosSettingsRegistered.listen((IosNotificationSettings settings) {
      print("Settings registered: $settings");
    });
    _firebaseMessaging.getToken().then((String token) {
      assert(token != null);
      SharedPreferencesHelper.setFirebaseToken(token);
    });
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }
}

Splash 只是一个启动页面,布尔loggedOut 参数只是说不要转发到登录页面。

标签: flutter

解决方案


不要忘记添加with WidgetsBindingObserver到您的状态类

class YourClass extends StatefulWidget { ....

class _YourClassState extends State<BottomNavigator> with WidgetsBindingObserver { ...

 @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  AppLifecycleState _notification;

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    switch (state) {
      case AppLifecycleState.paused:
        print("Paused");
        setState(() {
          _notification = state;
        });
        break;
      case AppLifecycleState.inactive:
        setState(() {
          _notification = state;
        });
        print("inactive");
        break;
      case AppLifecycleState.suspending:
        setState(() {
          _notification = state;
        });
        print("suspending");
        break;
      case AppLifecycleState.resumed:
        setState(() {
          _notification = state;
        });
        print("resumed");
        break;
    }
  }

并更改您的应用程序状态_notification

例如

@override
  Widget build(BuildContext context) {
    return _notification == AppLifecycleState.inactive
        ? Scaffold(
            body: Text("inactive"),
          )
        : YourRealWidget()

在此处输入图像描述

你可以从这里查看更多关于 WidgetsBindingObserver 的信息


推荐阅读