简体   繁体   中英

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:

  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?

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). 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.

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.

I use this for chatApp to track the app State. I wrap the 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 .

I haven't tested this, but screen state in the pub might be what you're looking for.

Big thanks to @mario-francois I got the following to work for me:

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) {
    ...
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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