Greg Perry

Nov 26, 2021

6 min read

A Better Flutter App #7

Supply lifecycle event handling with ease.

One of a series of articles detailing a comprehensive starter app. This app is generated by a template offered by the package, app_template, which uses the underlying framework, mvc_application, based on the MVC design pattern.

I Like Screenshots. Tap Caption For Gists.

No Moving Pictures, No Social Media

Let’s begin.

Other Stories by Greg Perry

An Eventful Lifecycle

Using the MVC framework, mvc_application, the starter app binds with the device platform’s lifecycle linking a number of event handlers — one of which involves the function called, didChangeAppLifecycleState(). As for the starter app, such a function proves helpful in stopping and starting Flutter’s Timer object that periodically displays in red a word-pair inside the Counter app. This will be demonstrated in this article possibly giving you an idea of how to properly work with Timer objects. Note the screenshot below of the didChangeAppLifecycleState() function. It conveys all the possible ‘lifecycle events’ that can occur and thus are represented by the parameter, state.

When this app starts up, Flutter’s Timer object is eventually instantiated in the controller, WordPairsTimer. It’s there in the controller’s initTimer() function (see second screenshot below) where the Timer object is then assigned to the instance variable, timer.

All this is done, in turn, inside the controller, CounterController, when the ‘Counter app’ screen is first displayed. In the first screenshot below, you can see the ‘CounterControllercontroller is assigned to the screen’s State object, _ConterPageState. Note, this State object is of type, StateMVC, and assigning the controller to it will allow that controller to then bind to the device platform’s event handling. Further on in that screenshot, the State object’s initState() function is displayed to you merely for demonstration purposes.

You see, it is within that initState() function that the State object calls the initState() function of any and all controllers assign to it. Thus, in the second screenshot, the Timer object is instantiated in the CounterController’s initState() function, but not before, the ‘timer controller’, WordPairsTimer, is also assigned to the State object, _ConterPageState. Again, doing so will bind that controller to the app’s lifecycle events as well.

By the way, below is a screenshot of a StateMVC object’s initState() function. You can readily see it’s there where the initState() function of every controller assigned to it is called. It is also there, in fact, where every StateMVC is bound to the host device’s lifecycle events using the WidgetsBinding class. In turn, controllers work through their assigned StateMVC objects to recognize the device’s lifecycle events. With me so far?


A Time and Place for a Timer

In observing the gif file below, note it begins in the Counter app, but then cycles through the other two apps before returning back. In this case, the State object, _CounterPageState, will call its deactivate() function when we move off the Counter app. Because it is of the type, StateMVC, the State object will cycle through any and all of its ‘attached’ controller objects and call their corresponding deactivate() functions as well. As you see below, the WordPairsTimer controller cancels its Timer object when ‘deactivated.’ An appropriate action as the Timer would continue and would unnecessarily take up precious CPU cycles.

Going Full Circle In Cycle

Time To Pause Then Resume

However, a tap on the app bringing it back to the forefront will call the didChangeAppLifecycleState() function once again. This time it’s the value, AppLifecycleState.resumed, that’s passed calling the initTimer() function and initiating another Timer object to resume displaying the word pairs. Finally, a tap on the stop button and swiping the app away will once again ‘cancel’ the Timer object before the whole app is terminated. A good practice when dealing with Timer objects.

Let’s leave it at that for now. Event handling is yet another crucial functionality every production-worthy Flutter app should have in hand. The MVC framework allows for this with ease.


A Better Flutter App #8

Using a InheritedWidget

→ Other Stories by Greg Perry