1+ import 'dart:ui' ;
2+
13import 'package:flutter/foundation.dart' ;
24import 'package:flutter/material.dart' ;
35
46abstract class LifecycleState <T extends StatefulWidget > extends State <T >
57 with WidgetsBindingObserver {
8+ AppLifecycleState ? _lifecycleState;
9+
610 @override
711 void initState () {
812 super .initState ();
13+ _lifecycleState = WidgetsBinding .instance.lifecycleState;
914 WidgetsBinding .instance.addObserver (this );
1015 }
1116
@@ -15,23 +20,87 @@ abstract class LifecycleState<T extends StatefulWidget> extends State<T>
1520 super .dispose ();
1621 }
1722
23+ @override
24+ Future <AppExitResponse > didRequestAppExit () async {
25+ onExitRequested ();
26+ return AppExitResponse .exit;
27+ }
28+
29+ /// [App Lifecycle Listener] (https://miro.medium.com/v2/resize:fit:1400/0*bN0QtrIRWGDMC9LJ)
30+ ///
31+ /// detached -> resumed -|
32+ /// ^ v
33+ /// | inactive
34+ /// paused <- hidden <--|
35+ ///
1836 @override
1937 void didChangeAppLifecycleState (AppLifecycleState state) {
38+ final AppLifecycleState ? previousState = _lifecycleState;
39+ if (state == previousState) {
40+ // Transitioning to the same state twice doesn't produce any notifications (but also won't actually occur).
41+ return ;
42+ }
43+ _lifecycleState = state;
2044 switch (state) {
2145 case AppLifecycleState .resumed:
2246 onResumed ();
2347 break ;
2448 case AppLifecycleState .inactive:
25- onPaused ();
49+ if (previousState == AppLifecycleState .hidden) {
50+ onShow ();
51+ } else if (previousState == null ||
52+ previousState == AppLifecycleState .resumed) {
53+ onInactive ();
54+ }
55+ break ;
56+ case AppLifecycleState .hidden:
57+ if (previousState == AppLifecycleState .paused) {
58+ onRestart ();
59+ } else if (previousState == null ||
60+ previousState == AppLifecycleState .inactive) {
61+ onHidden ();
62+ }
2663 break ;
2764 case AppLifecycleState .paused:
28- onInactive ();
65+ if (previousState == null ||
66+ previousState == AppLifecycleState .hidden) {
67+ onPaused ();
68+ }
2969 break ;
3070 case AppLifecycleState .detached:
3171 onDetached ();
3272 break ;
3373 default :
3474 }
75+
76+ // At this point, it can't be null anymore.
77+ if (_lifecycleState != null ) {
78+ onStateChange (_lifecycleState! );
79+ }
80+ }
81+
82+ void onExitRequested () {
83+ if (kDebugMode) {
84+ print ("on exit requested" );
85+ }
86+ }
87+
88+ void onStateChange (AppLifecycleState state) {
89+ if (kDebugMode) {
90+ print ("on state change: $state " );
91+ }
92+ }
93+
94+ void onShow () {
95+ if (kDebugMode) {
96+ print ("on show" );
97+ }
98+ }
99+
100+ void onHidden () {
101+ if (kDebugMode) {
102+ print ("on hidden" );
103+ }
35104 }
36105
37106 void onResumed () {
@@ -57,4 +126,10 @@ abstract class LifecycleState<T extends StatefulWidget> extends State<T>
57126 print ("on detached" );
58127 }
59128 }
129+
130+ void onRestart () {
131+ if (kDebugMode) {
132+ print ("on restart" );
133+ }
134+ }
60135}
0 commit comments