In Flutter, is there a way to update widgets when the user leaves the app and come right back to it? My app is time based, and it would be helpful to update the time as soon as it can.
问题:
回答1:
You can listen to lifecycle events
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.detatched:
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((){}))
);
}
...
}
回答2:
Using system Channel:
import 'package:flutter/services.dart';
SystemChannels.lifecycle.setMessageHandler((msg){
debugPrint('SystemChannels> $msg');
if(msg==AppLifecycleState.resumed.toString())setState((){});
});
`
回答3:
Simple way:
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:
}
});
}
just add handleAppLifecycleState()
in your 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');
}
}
For more details you refer documentation
回答4:
For deeply testing, I think the results are worth for read. If you are curious about which method you should use, just read the below: (Tested on Android)
There are three methods for LifeCycle solution.
WidgetsBindingObserver
SystemChannels.lifecycle
- flutter-android-lifecycle-plugin
The main difference between WidgetsBindingObserver
and SystemChannels.lifecycle
is that WidgetsBindingObserver
have more capables If you have a bunch of widgets that need to listen LifeCycle. SystemChannels
is more low layer, and used by WidgetsBindingObserver
.
After several testing, If you use SystemChannels
after runApp
, and home widget mixin with WidgetsBindingObserver
, home widget would be failed, because SystemChannels.lifecycle.setMessageHandler
override the home's method.
So If you want to use a global, single method, go for SystemChannels.lifecycle
, others for WidgetsBindingObserver
.
And what about the third method? This is only for Android, and If you must bind your method before runApp
, this is the only way to go.
回答5:
Here’s an example of how to observe the lifecycle status of the containing activity (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()));
}