Flutter is designed to support mobile apps that run on both Android and iOS, as well as interactive apps that you want to run on your web pages or on the desktop.
It is a combination of stateful and stateless widgets. Like all frameworks, Flutter also has a lifecycle associated with all the apps that our Flutter app uses. is managed by lifecycle In this article, we will take a look at different types of apps available in the flutter app, lifecycle.
Flutter uses the Dart programming language, which is different from the JavaScript that React Native uses. Dart is easy to learn for developers who are already familiar with JavaScript. Flutter apps have a native look and feel on both Android and iOS devices, thanks to Flutter's use of the Cupertino widgets.
There is a method called when the system put the app in the background or return the app to foreground named didChangeAppLifecycleState
.
Example with widgets:
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)
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();
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With