This tutorial is about how to detect when a Flutter application comes to the foreground or goes to the background. This includes the list of possible application lifecycle states with the explanation.
A running Flutter application has a lifecycle state. Detecting state changes is necessary for some applications. For example, it can be necessary to fetch the latest data when the application goes back to the foreground or pause a running task when it goes to the background. This tutorial explains the possible states and how to detect when the state changes.
Application Lifecycle States
First, you need to understand the possible states of an application. Flutter has four application states. Below is the list of states along with the explanation.
Resumed state
In this state, the application is visible to the user (in the foreground) and it can receive user input.
Inactive state
In this state, the application may still be visible to the user (in the foreground) but it doesn't receive user input and it may go to the paused state at any time.
On Android, it can happen when the focus changes to another activity, such as a phone call, a system dialog, a split-screen application, or a pop-up window. On iOS, it can happen when there is a phone call, entering the app switcher, responding to a TouchID request, or when the UIViewController is transitioning.
Paused state
In this state, the application is not visible to the user and not responding to user input. It runs in the background.
Detached state
In this state, the application is detached from any host views. The possible conditions are when the engine first initializes (in the process of attaching a view) or being destroyed from a Navigator pop (such as pressing the back button on the application's home page).
Detect Lifecycle State Change
Detecting lifecycle changes in Flutter is quite simple. You need to create a State
class that uses the WidgetsBindingObserver
interface. If you look at the interface, there is a method named didChangeAppLifecycleState
. It's called when the application state changes, such as when it goes to the background or returns to the foreground. The method will be invoked with an argument whose value is the current state. Therefore, you can override the method to listen to the events when the lifecycle state changes.
To make it works, the State
class has to be registered as a binding observer by calling WidgetsBinding
's addObserver
method inside the initState
method. You also need to call WidgetsBinding
's removeObserver
to unregister the class as an observer when it's removed from the tree.
class _GetDeviceLocale extends State<DetectLifecycleState>
with WidgetsBindingObserver {
@override
void initState() {
WidgetsBinding.instance.addObserver(this);
super.initState();
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
switch (state) {
// Write your code
}
}
}
Full Code
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Woolha.com Flutter Tutorial',
home: DetectLifecycle(),
);
}
}
class DetectLifecycle extends StatefulWidget {
const DetectLifecycle({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() {
return _DetectLifecycleState();
}
}
class _DetectLifecycleState extends State<DetectLifecycle>
with WidgetsBindingObserver {
@override
void initState() {
WidgetsBinding.instance.addObserver(this);
super.initState();
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
switch (state) {
case AppLifecycleState.resumed:
print("RESUMED");
break;
case AppLifecycleState.inactive:
print("INACTIVE");
break;
case AppLifecycleState.paused:
print("PAUSED");
break;
case AppLifecycleState.detached:
print("DETACHED");
break;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Woolha.com Flutter Tutorial'),
backgroundColor: Colors.teal,
),
body: const SizedBox(
width: double.infinity,
child: Center(
child: Text('Woolha.com'),
),
),
);
}
}
Summary
There are four application lifecycle states: resumed, inactive, paused, and detached. To detect when the state changes, just implement WidgetsBindingObserver
and override the didChangeAppLifecycleState
method.