Reputation: 2254
Are there any Activity
lifecycle methods in Flutter apps?
Like:
onCreate()
onResume()
onDestroy()
Or:
viewDidload()
viewWillAppear()
How to handle application lifecycle when making an app with Flutter?
Upvotes: 42
Views: 50382
Reputation: 6980
Flutter version 3.13 added AppLifecycleListener so now you can listen to show, pause , resume , restart etc.
_listener = AppLifecycleListener(
onShow: () => _handleTransition('show'),
onResume: () => _handleTransition('resume'),
onHide: () => _handleTransition('hide'),
onInactive: () => _handleTransition('inactive'),
onPause: () => _handleTransition('pause'),
onDetach: () => _handleTransition('detach'),
onRestart: () => _handleTransition('restart'),
// This fires for each state change. Callbacks above fire only for
// specific state transitions.
onStateChange: _handleStateChange,
);
For more info check this example from flutter repo
Upvotes: 12
Reputation:
There is a method called when the system put the app in the background or return the app to foreground named didChangeAppLifecycleState
.
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 new Text('Last notification: $_notification');
}
}
Also there are CONSTANTS to know the states that an application can be in, eg:
The usage of these constants would be the value of the constant e.g:
const AppLifecycleState(state)
Upvotes: 59
Reputation: 268514
Run the following code, press the home button and then reopen the app to see it working. There are 4 AppLifecycleState
:
resumed: The application is visible and responding to user input.
inactive: The application is in an inactive state and is not receiving user input.
paused: The application is not currently visible to the user, not responding to user input, and running in the background.
detached: The application is still hosted on a flutter engine but is detached from any host views.
Null safe code:
class MyPage extends StatefulWidget {
@override
_MyPageState createState() => _MyPageState();
}
class _MyPageState extends State<MyPage> with WidgetsBindingObserver {
@override
void initState() {
super.initState();
WidgetsBinding.instance!.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance!.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
print('Current state = $state');
}
@override
Widget build(BuildContext context) => Scaffold();
}
Upvotes: 9
Reputation: 30765
To be notified when app goes to foreground or route popped you can inherit LifecycleState
class and override onResume()
and onPause()
methods. LifecycleState
class:
/// Inherit this State to be notified of lifecycle events, including popping and pushing routes.
///
/// Use `pushNamed()` or `push()` method to track lifecycle events when navigating to another route.
abstract class LifecycleState <T extends StatefulWidget> extends State<T>
with WidgetsBindingObserver {
ResumeResult resumeResult = new ResumeResult();
bool _isPaused = false;
AppLifecycleState lastAppState = AppLifecycleState.resumed;
void onResume() {}
void onPause() {}
/// Use instead of Navigator.push(), it fires onResume() after route popped
Future<T> push<T extends Object>(BuildContext context, Route<T> route, [String source]) {
_isPaused = true;
onPause();
return Navigator.of(context).push(route).then((value) {
_isPaused = false;
resumeResult.data = value;
resumeResult.source = source;
onResume();
return value;
});
}
/// Use instead of Navigator.pushNamed(), it fires onResume() after route popped
Future<T> pushNamed<T extends Object>(BuildContext context, String routeName, {Object arguments}) {
_isPaused = true;
onPause();
return Navigator.of(context).pushNamed<T>(routeName, arguments: arguments).then((value) {
_isPaused = false;
resumeResult.data = value;
resumeResult.source = routeName;
onResume();
return value;
});
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.paused) {
if (!_isPaused) {
onPause();
}
} else if (state == AppLifecycleState.resumed &&
lastAppState == AppLifecycleState.paused) {
if (!_isPaused) {
onResume();
}
}
lastAppState = state;
}
}
class ResumeResult {
dynamic data;
String source;
}
Also make sure to start push new routes using push()
or pushNamed()
method.
Upvotes: 1