简体   繁体   English

Flutter:屏幕关闭时的`setState()`,或者如何检测屏幕是否打开?

[英]Flutter: `setState()` when screen off, or how to detect if screen is on?

TLDR: I have a problem that should be solved if there is answer to one of the below questions: TLDR:如果有以下问题之一的答案,我有一个应该解决的问题:

  1. Is there a way I can detect if the screen is on eg有没有办法可以检测屏幕是否打开,例如
if (SCREEN IS ON) {
  setState(() {});  // i.e. update displayed widgets
}
  1. Is there a way to call setState() so that is finishes when the screen is off?有没有办法调用setState()以便在屏幕关闭时完成?

More details:更多细节:

I have an app that plays audio.我有一个播放音频的应用程序。 When the screen is on, the widgets update via setState() (eg to display the progress of the audio).当屏幕打开时,小部件通过setState()更新(例如,显示音频的进度)。 Nonetheless it would be nice to let a user turn off their screen to save battery - however if I call setState() when the screen is off, it seems that the app waits for the screen to be turned back on before finishing the setState() code.尽管如此,让用户关闭屏幕以节省电池会很好 - 但是如果我在屏幕关闭时调用setState() ,似乎应用程序在完成setState()之前等待屏幕重新打开代码。

Hence I am hoping to determine if I can detect and only call setState() when the screen is on, alternatively can I call setState() when the screen is off so that is completes.因此,我希望确定是否可以检测到并且仅在屏幕打开时调用setState() ,或者我可以在屏幕关闭时调用setState()以便完成。

I use this for chatApp to track the app State.我将它用于 chatApp 来跟踪应用程序 State。 I wrap the MaterialApp.我包装了 MaterialApp。 With some changes you could do what you want.通过一些改变,你可以做你想做的事。

import 'package:flutter/material.dart';
import 'package:flutter_stripe/flutter_stripe.dart';

import 'constants/credentials.dart';
import 'domain/repositories/my_user_repository.dart';

class AppLifeCycleManager extends StatefulWidget {
  final Widget child;
  final MyUserRepository myUserRepo;

  const AppLifeCycleManager(
      {Key? key, required this.child, required this.myUserRepo})
      : super(key: key);

  @override
  _AppLifeCycleManagerState createState() => _AppLifeCycleManagerState();
}

class _AppLifeCycleManagerState extends State<AppLifeCycleManager>
    with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();

    widget.myUserRepo.setOnlineCustomer();
    WidgetsBinding.instance.addObserver(this);
    // set the publishable key for Stripe - this is mandatory
    Stripe.publishableKey = pkTest;
  }

  @override
  Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
    super.didChangeAppLifecycleState(state);

    switch (state) {
      case AppLifecycleState.paused:
        widget.myUserRepo.setInactiveCustomer();
        break;
      case AppLifecycleState.resumed:
        widget.myUserRepo.setOnlineCustomer();
        break;
      case AppLifecycleState.inactive:
        widget.myUserRepo.setInactiveCustomer();
        break;
      case AppLifecycleState.detached:
        widget.myUserRepo.setInactiveCustomer();
        break;
    }
  }

  @override
  Widget build(BuildContext context) {
    return widget.child;
  }

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

mounted might be what you are looking for. 安装的可能是您正在寻找的。 Alternatively, you could check the AppLifecycleState by using WidgetsBindingObserver .或者,您可以使用WidgetsBindingObserver 检查 AppLifecycleState

I haven't tested this, but screen state in the pub might be what you're looking for.我没有对此进行测试,但酒吧中的屏幕 state可能是您正在寻找的。

Big thanks to @mario-francois I got the following to work for me:非常感谢@mario-francois,我得到了以下工作:

import 'package:flutter/material.dart';

class MyPage extends StatefulWidget {
  MyPage({Key? key}) : super(key: key);

  @override
  _MyPageState createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> with WidgetsBindingObserver {
  bool screenOn = true;

  @override
  Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
    super.didChangeAppLifecycleState(state);
    switch (state) {
      case AppLifecycleState.paused:// screen off/navigate away
      // this.screenOn = false;
        break;
      case AppLifecycleState.resumed:  // screen on/navigate to
        this.screenOn = true;
        break;
      case AppLifecycleState.inactive:  // screen off/navigate away
        this.screenOn = false;
        break;
      case AppLifecycleState.detached:
        break;
    }
  }

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

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

  @override
  Widget build(BuildContext context) {
    ...
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM