颤动:恢复小部件更新小部件?

Jos*_*ren 19 dart flutter

在Flutter中,有没有办法在用户离开应用程序并更新回来时更新小部件?我的应用程序是基于时间的,尽快更新时间会很有帮助.

Gün*_*uer 32

您可以收听生命周期事件

import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';

class LifecycleEventHandler extends WidgetsBindingObserver {
  LifecycleEventHandler({this.resumeCallBack, this.suspendingCallBack});

  final AsyncCallback resumeCallBack;
  final AsyncCallback suspendingCallBack;

  @override
  Future<Null> didChangeAppLifecycleState(AppLifecycleState state) async {
    switch (state) {
      case AppLifecycleState.inactive:
      case AppLifecycleState.paused:
      case AppLifecycleState.suspending:
        await suspendingCallBack();
        break;
      case AppLifecycleState.resumed:
        await resumeCallBack();
        break;
    }
  }
}


class AppWidgetState extends State<AppWidget> {
  void initState() {
    super.initState();

    WidgetsBinding.instance.addObserver(
        new LifecycleEventHandler(resumeCallback(() => setState((){}))
    );
  }
  ...
}
Run Code Online (Sandbox Code Playgroud)

  • FutureVoidCallback在哪里定义?我在flutter软件包的源代码中找不到它,谷歌也没有帮助吗? (2认同)
  • @ChrisCrowe你是对的。您需要自己声明。`typedef FutureVoidCallback = Future &lt;void&gt; Function();` (2认同)

Tok*_*yet 16

对于深度测试,我认为结果值得一读。如果您对应该使用哪种方法感到好奇,请阅读以下内容:(在 Android 上测试)

LifeCycle 解决方案共有三种方法。

  1. WidgetsBindingObserver
  2. SystemChannels.lifecycle
  3. flutter-android-lifecycle-plugin

WidgetsBindingObserver和之间的主要区别SystemChannels.lifecycleWidgetsBindingObserver有更多的能力 如果你有一堆需要听生命周期的小部件。SystemChannels更底层,被WidgetsBindingObserver.

经过多次测试,如果你使用SystemChannelsafter runApp,和 home widget 混合使用WidgetsBindingObserver, home widget 会失败,因为SystemChannels.lifecycle.setMessageHandler覆盖了 home 的方法。

因此,如果您想使用全局的单一方法,请使用 for SystemChannels.lifecycle,其他适用于WidgetsBindingObserver.

那么第三种方法呢?这仅适用于Android,如果您必须在之前 绑定您的方法runApp,这是唯一的方法。


Rah*_*dik 14

简单的方法:

import 'package:flutter/services.dart';

handleAppLifecycleState() {
    AppLifecycleState _lastLifecyleState;
    SystemChannels.lifecycle.setMessageHandler((msg) {

     print('SystemChannels> $msg');

        switch (msg) {
          case "AppLifecycleState.paused":
            _lastLifecyleState = AppLifecycleState.paused;
            break;
          case "AppLifecycleState.inactive":
            _lastLifecyleState = AppLifecycleState.inactive;
            break;
          case "AppLifecycleState.resumed":
            _lastLifecyleState = AppLifecycleState.resumed;
            break;
          case "AppLifecycleState.suspending":
            _lastLifecyleState = AppLifecycleState.suspending;
            break;
          default:
        }
    });
  }
Run Code Online (Sandbox Code Playgroud)

只需添加handleAppLifecycleState()您的init()

或者

class AppLifecycleReactor extends StatefulWidget {
      const AppLifecycleReactor({ Key key }) : super(key: key);

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

    class _AppLifecycleReactorState extends State<AppLifecycleReactor> 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) {
        setState(() { _notification = state; });
      }

      @override
      Widget build(BuildContext context) {
        return Text('Last notification: $_notification');
      }
    }
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅文档


Kar*_*mal 12

import 'package:flutter/material.dart';

abstract class LifecycleWatcherState<T extends StatefulWidget> extends State<T>
    with WidgetsBindingObserver {
  @override
  Widget build(BuildContext context) {
    return null;
  }

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

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

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    switch (state) {
      case AppLifecycleState.resumed:
        onResumed();
        break;
      case AppLifecycleState.inactive:
        onPaused();
        break;
      case AppLifecycleState.paused:
        onInactive();
        break;
      case AppLifecycleState.detached:
        onDetached();
        break;
    }
  }

  void onResumed();
  void onPaused();
  void onInactive();
  void onDetached();
}
Run Code Online (Sandbox Code Playgroud)

例子

class ExampleStatefulWidget extends StatefulWidget {
  @override
  _ExampleStatefulWidgetState createState() => _ExampleStatefulWidgetState();
}

class _ExampleStatefulWidgetState
    extends LifecycleWatcherState<ExampleStatefulWidget> {
  @override
  Widget build(BuildContext context) {
    return Container();
  }

  @override
  void onDetached() {

  }

  @override
  void onInactive() {

  }

  @override
  void onPaused() {

  }

  @override
  void onResumed() {

  }
}
Run Code Online (Sandbox Code Playgroud)

  • @cwhisperer,您可以使用 SizedBox() instate of null 或删除“Widget build(BuildContext context)”我没有测试它,但也许它不会产生问题。 (2认同)

Upa*_*Jah 6

使用系统频道:

import 'package:flutter/services.dart';

SystemChannels.lifecycle.setMessageHandler((msg){
  debugPrint('SystemChannels> $msg');
  if(msg==AppLifecycleState.resumed.toString())setState((){});
});
Run Code Online (Sandbox Code Playgroud)

`

  • 这对其他人来说可能很明显,但我花了一段时间才弄清楚我需要在 Flutter runApp 调用之后将其移动到某个位置。 (3认同)

小智 6

这里\xe2\x80\x99是一个如何观察包含Activity的生命周期状态的示例(适用于Android开发人员的Flutter):

\n\n
import \'package:flutter/widgets.dart\';\n\nclass LifecycleWatcher extends StatefulWidget {\n  @override\n  _LifecycleWatcherState createState() => _LifecycleWatcherState();\n}\n\nclass _LifecycleWatcherState extends State<LifecycleWatcher> with WidgetsBindingObserver {\n  AppLifecycleState _lastLifecycleState;\n\n  @override\n  void initState() {\n    super.initState();\n    WidgetsBinding.instance.addObserver(this);\n  }\n\n  @override\n  void dispose() {\n    WidgetsBinding.instance.removeObserver(this);\n    super.dispose();\n  }\n\n  @override\n  void didChangeAppLifecycleState(AppLifecycleState state) {\n    setState(() {\n      _lastLifecycleState = state;\n    });\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    if (_lastLifecycleState == null)\n      return Text(\'This widget has not observed any lifecycle changes.\', textDirection: TextDirection.ltr);\n\n    return Text(\'The most recent lifecycle state this widget observed was: $_lastLifecycleState.\',\n        textDirection: TextDirection.ltr);\n  }\n}\n\nvoid main() {\n  runApp(Center(child: LifecycleWatcher()));\n}\n
Run Code Online (Sandbox Code Playgroud)\n


小智 6

使用“WidgetsBindingObserver”或“SystemChannels.lifecycle”检测 onResume 事件的解决方案仅在应用程序完全进入后台时才起作用,例如在锁定屏幕事件期间或切换到另一个应用程序期间。如果用户在应用程序的屏幕之间导航,它将不起作用。如果您想在同一应用程序的不同屏幕之间切换时检测 onResume 事件,请使用此处的visibility_Detector库: https: //pub.dev/packages/visibility_detector

  @override
Widget build(BuildContext context) {
  return VisibilityDetector(
    key: Key('my-widget-key'),
    onVisibilityChanged: (visibilityInfo) {
      num visiblePercentage = visibilityInfo.visibleFraction * 100;
      debugPrint(
          'Widget ${visibilityInfo.key} is ${visiblePercentage}% visible');
      if(visiblePercentage == 100){
                debugPrint("Resumed !");
              }
    },
    child: someOtherWidget,
  );
}
Run Code Online (Sandbox Code Playgroud)