【问题标题】:Is there a way to repaint the screen or navigate to a different screen on AppLifecycleState.paused in Flutter有没有办法在 Flutter 中的 AppLifecycleState.paused 上重新绘制屏幕或导航到不同的屏幕
【发布时间】:2019-03-22 21:09:36
【问题描述】:

我有一个包含敏感媒体信息的 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


    【解决方案1】:

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

    class YourClass extends StatefulWidget { ....

    class _YourClassState extends State&lt;BottomNavigator&gt; 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 from here的更多信息

    【讨论】:

    • 有没有办法在全球范围内做到这一点?我不想在每个屏幕上都实现这个。
    • 您可以在您的根目录中实现该代码,因此这将适用于您的每个选项卡,它可以是 CupertinoTabBar BottomNavigationBarTabBar 如果您使用任何标签,
    • 非常感谢!
    • 如果我把它放在我的根小部件中,这对我不起作用。
    猜你喜欢
    • 2019-03-12
    • 2019-06-07
    • 2022-08-09
    • 2018-10-06
    • 2020-03-06
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 2019-12-02
    相关资源
    最近更新 更多