在Flutter中,有没有办法在用户离开应用程序并立即返回时更新小部件?我的应用程序是基于时间的,尽快更新时间会很有帮助。
答案 0 :(得分:15)
您可以收听生命周期事件
class LifecycleEventHandler extends WidgetsBindingObserver {
LifecycleEventHandler({this.resumeCallBack, this.suspendingCallBack});
final FutureVoidCallback resumeCallBack;
final FutureVoidCallback 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((){}))
);
}
...
}
答案 1 :(得分:5)
使用系统频道:
import 'package:flutter/services.dart';
SystemChannels.lifecycle.setMessageHandler((msg){
debugPrint('SystemChannels> $msg');
if(msg==AppLifecycleState.resumed.toString())setState((){});
});
`
答案 2 :(得分:5)
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() {
}
}
答案 3 :(得分:2)
简单方法:
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()
OR
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
答案 4 :(得分:0)
对于深入测试,我认为结果值得一读。如果您对应该使用哪种方法感到好奇,请阅读以下内容:(在Android上经过测试)
LifeCycle解决方案有三种方法。
WidgetsBindingObserver
SystemChannels.lifecycle
WidgetsBindingObserver
和SystemChannels.lifecycle
之间的主要区别在于,WidgetsBindingObserver
具有更多的功能,如果您有一堆需要监听LifeCycle的小部件。 SystemChannels
是较低层,由WidgetsBindingObserver
使用。
经过几次测试,如果在SystemChannels
之后使用runApp
,并且home小部件与WidgetsBindingObserver
混合,则home小部件将失败,因为SystemChannels.lifecycle.setMessageHandler
会覆盖home方法。
因此,如果要使用全局的单一方法,请使用SystemChannels.lifecycle
,其他使用WidgetsBindingObserver
。
那第三种方法呢?这仅适用于Android,如果必须在之前 runApp
之前绑定方法,这是唯一的方法。
答案 5 :(得分:0)
下面是一个如何观察包含活动(Flutter for Android developers)的生命周期状态的示例:
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()));
}
答案 6 :(得分:0)
使用“WidgetsBindingObserver”检测 onResume 事件的解决方案 或“SystemChannels.lifecycle”仅在应用程序完全进入后台时才起作用,例如在锁定屏幕事件期间或在切换到另一个应用程序期间。如果用户在应用程序的屏幕之间导航,它将不起作用。如果即使在同一应用程序的不同屏幕之间切换时也想检测 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,
);
}