dart Flutter:恢复时更新小部件?

6pp0gazn  于 2023-03-05  发布在  Flutter
关注(0)|答案(9)|浏览(180)

在Flutter中,当用户离开应用程序并返回时,是否有方法更新小部件?我的应用程序是基于时间的,尽快更新时间会很有帮助。

r55awzrz

r55awzrz1#

您可以通过执行以下操作来监听生命周期事件,例如:

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

class LifecycleEventHandler extends WidgetsBindingObserver {
  final AsyncCallback resumeCallBack;
  final AsyncCallback suspendingCallBack;

  LifecycleEventHandler({
    this.resumeCallBack,
    this.suspendingCallBack,
  });

  @override
  Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
    switch (state) {
      case AppLifecycleState.resumed:
        if (resumeCallBack != null) {
          await resumeCallBack();
        }
        break;
      case AppLifecycleState.inactive:
      case AppLifecycleState.paused:
      case AppLifecycleState.detached:
        if (suspendingCallBack != null) {
          await suspendingCallBack();
        }
        break;
    }
  }
}


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

    WidgetsBinding.instance.addObserver(
      LifecycleEventHandler(resumeCallBack: () async => setState(() {
        // do something
      }))
    );
  }
  ...
}
zpjtge22

zpjtge222#

使用系统通道:

import 'package:flutter/services.dart';

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

'

qqrboqgw

qqrboqgw3#

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();
}

示例

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() {

  }
}
6tdlim6h

6tdlim6h4#

对于深度测试,我认为结果值得一读。如果你对应该使用哪种方法感到好奇,请阅读以下内容:(在Android上测试)
生命周期解决方案有三种方法。

  1. WidgetsBindingObserver
  2. SystemChannels.lifecycle
  3. flutter-android-lifecycle-plugin
    WidgetsBindingObserverSystemChannels.lifecycle之间的主要区别是WidgetsBindingObserver有更多的功能,如果你有一堆小部件需要监听生命周期。SystemChannels是更低的层,由WidgetsBindingObserver使用。
    经过多次测试,如果您在runApp之后使用SystemChannels,并且使用WidgetsBindingObserver混合家庭小部件,家庭小部件将失败,因为SystemChannels.lifecycle.setMessageHandler覆盖家庭的方法。
    所以如果你想使用一个全局的,单一的方法,选择SystemChannels.lifecycle,其他的选择WidgetsBindingObserver
    那么第三种方法呢,这只适用于Android,如果你必须在**runApp之前绑定你的方法,这是唯一的方法。
vptzau2j

vptzau2j5#

简单方法:

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:
        }
    });
  }

只需将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');
      }
    }

有关详细信息,请参阅documentation

qlfbtfca

qlfbtfca6#

以下示例说明了如何观察包含Activity的生命周期状态(适用于Android开发人员的Flutter):

import 'package:flutter/widgets.dart';

class LifecycleWatcher extends StatefulWidget {
  @override
  _LifecycleWatcherState createState() => _LifecycleWatcherState();
}

class _LifecycleWatcherState extends State<LifecycleWatcher> with WidgetsBindingObserver {
  AppLifecycleState _lastLifecycleState;

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

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

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    setState(() {
      _lastLifecycleState = state;
    });
  }

  @override
  Widget build(BuildContext context) {
    if (_lastLifecycleState == null)
      return Text('This widget has not observed any lifecycle changes.', textDirection: TextDirection.ltr);

    return Text('The most recent lifecycle state this widget observed was: $_lastLifecycleState.',
        textDirection: TextDirection.ltr);
  }
}

void main() {
  runApp(Center(child: LifecycleWatcher()));
}
stszievb

stszievb7#

使用“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,
  );
}
gmxoilav

gmxoilav8#

如果你只想在一个页面上执行onResume方法,你可以在你的页面上添加这个方法:

var lifecycleEventHandler;

@override
  void initState() {
    super.initState();

    ///To listen onResume method
    lifecycleEventHandler = LifecycleEventHandler(
        resumeCallBack: () async {
          //do something
        }
    );
    WidgetsBinding.instance.addObserver(lifecycleEventHandler);
  }

@override
  void dispose() {
    if(lifecycleEventHandler != null)
      WidgetsBinding.instance.removeObserver(lifecycleEventHandler);

    super.dispose();
  }

并将LifecycleEventHandler类作为此帖子的第一个答案:

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

class LifecycleEventHandler extends WidgetsBindingObserver {
  final AsyncCallback resumeCallBack;
  final AsyncCallback suspendingCallBack;

  LifecycleEventHandler({
    this.resumeCallBack,
    this.suspendingCallBack,
  });

  @override
  Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
    switch (state) {
      case AppLifecycleState.resumed:
        if (resumeCallBack != null) {
          await resumeCallBack();
        }
        break;
      case AppLifecycleState.inactive:
      case AppLifecycleState.paused:
      case AppLifecycleState.detached:
        if (suspendingCallBack != null) {
          await suspendingCallBack();
        }
        break;
    }
  }
}
siotufzp

siotufzp9#

如果需要可靠的onOpen处理程序,则应该从initStateWidgetsBindingObserver docs调用它。
测试对象:

  • 应用程序的第一次启动。
  • 轻按任意系统按钮(返回、主页、最近使用的应用程序)以关闭应用程序,然后再次打开应用程序。

代码:

class MyWidgetState extends State<MyWidget> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    onOpen();
  }

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

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) onOpen();
  }

  void onOpen() {
    debugPrint('-------- OPEN --------');
  }

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

相关问题