onResume() and onPause() for widgets in Flutter
Tags: flutter, dart
Published: 2019-07-17 22:34:52

---
tags: flutter, dart,
title: onResume() and onPause() for widgets in Flutter
description: In this post we are going to take a look at widget states in Flutter. Coming from Android we are familiar with app states…
cover_image: https://cdn-images-1.medium.com/max/800/1*ROuBKDAhiWFl3jIbDvtinw.png
---


<p name="6a32" id="6a32" class="graf graf--p graf-after--figure">Hi guys, Today we are going to take a look at widget states in Flutter. Coming from Android we are familiar with app states (activity state) like onCreate, onResume and onPause, lets see the equivalent to these functions in Flutter.</p><h4 name="0e40" id="0e40" class="graf graf--h4 graf-after--p">Lets build an Scenario</h4><p name="631a" id="631a" class="graf graf--p graf-after--h4">We are building an Bank app that should request the user’s password each time the app is opened. In this case we can start by thinking where we should put the code that show a dialog requesting the password.</p><h4 name="9887" id="9887" class="graf graf--h4 graf-after--p">WidgetsBindingObserver</h4><p name="e2e5" id="e2e5" class="graf graf--p graf-after--h4">This class lets us receive notifications for many system and app changes. For example here is few functions available in this class:</p><ul class="postList"><li name="1ba6" id="1ba6" class="graf graf--li graf-after--p"><strong class="markup--strong markup--li-strong">didPopRoute()</strong><br>On Android, this is called when the user press the back button.</li><li name="6ba7" id="6ba7" class="graf graf--li graf-after--li"><strong class="markup--strong markup--li-strong">didChangeLocales(…)<br></strong>Called when the sytem notify the app that the user changed system’s language settings.</li><li name="7c5c" id="7c5c" class="graf graf--li graf-after--li"><strong class="markup--strong markup--li-strong">didChangeAppLifecycleState(…)<br></strong>This one is called when the system puts the app in background/foreground.</li></ul><p name="aae2" id="aae2" class="graf graf--p graf-after--li">We have two options when using it: <strong class="markup--strong markup--p-strong">extends, </strong>to get default behavior for all app/system changes or <strong class="markup--strong markup--p-strong">implements </strong>where we must implement all the handles.</p><h3 name="1978" id="1978" class="graf graf--h3 graf-after--p">Setting it up</h3><p name="7775" id="7775" class="graf graf--p graf-after--h3">Now that we know the WidgetsBindingObserver lets use it for our use case: request user’s password everytime the app is resumed.</p><ol class="postList"><li name="092a" id="092a" class="graf graf--li graf-after--p">Extend <strong class="markup--strong markup--li-strong">MyHomePage</strong> state class:</li></ol><pre name="d388" id="d388" class="graf graf--pre graf-after--li">class _MyHomePageState extends <strong class="markup--strong markup--pre-strong">State&lt;MyHomePage&gt;</strong> with <strong class="markup--strong markup--pre-strong">WidgetsBindingObserver </strong>{...}</pre><p name="fc83" id="fc83" class="graf graf--p graf-after--pre">2. Add the observer to the current <strong class="markup--strong markup--p-strong">WidgetsBinding</strong> instance:</p><p name="4ab8" id="4ab8" class="graf graf--p graf-after--p">To receive changes notifications we must register our observer, also we should unregister the observer in dispose() fuction to release resources reserved by our observer</p><pre name="ff32" id="ff32" class="graf graf--pre graf-after--p">@override<br>void initState() {<br>  super.initState();<br>  <strong class="markup--strong markup--pre-strong">WidgetsBinding.<em class="markup--em markup--pre-em">instance</em>.addObserver(this);</strong><br>}</pre><p name="59eb" id="59eb" class="graf graf--p graf-after--pre">Releasing resources…</p><pre name="a09d" id="a09d" class="graf graf--pre graf-after--p">@override<br>void dispose() {<br>  <strong class="markup--strong markup--pre-strong">WidgetsBinding.<em class="markup--em markup--pre-em">instance</em>.removeObserver(this);</strong><br>  super.dispose();<br>}</pre><p name="04f0" id="04f0" class="graf graf--p graf-after--pre">3. Listen for when the app enter in background or foreground state.<br>In this step all we need to do it to check wich state we received from the system and then react to those changes.</p><pre name="5642" id="5642" class="graf graf--pre graf-after--p"><strong class="markup--strong markup--pre-strong">@override<br>void didChangeAppLifecycleState(AppLifecycleState state) {</strong><br>  if(<strong class="markup--strong markup--pre-strong">state </strong>== AppLifecycleState.<strong class="markup--strong markup--pre-strong">resumed</strong>){<br>    _showPasswordDialog();<br>  }<br><strong class="markup--strong markup--pre-strong">}</strong></pre><p name="9119" id="9119" class="graf graf--p graf-after--pre">This way every time the user navigate away from our app and then come back, the _showPasswordDialog() will be called.</p><p name="4d6e" id="4d6e" class="graf graf--p graf-after--p">We can also check wether the user is leaving our app for example:</p><pre name="3216" id="3216" class="graf graf--pre graf-after--p">@override<br>void didChangeAppLifecycleState(AppLifecycleState state) {<br>  if(state == AppLifecycleState.<strong class="markup--strong markup--pre-strong">resumed</strong>){<br>    // <strong class="markup--strong markup--pre-strong">user returned to our app</strong><br>  }else if(state == AppLifecycleState.<strong class="markup--strong markup--pre-strong">inactive</strong>){<br>    // <strong class="markup--strong markup--pre-strong">app is inactive</strong><br>  }else if(state == AppLifecycleState.<strong class="markup--strong markup--pre-strong">paused</strong>){<br>    // <strong class="markup--strong markup--pre-strong">user is about quit our app temporally</strong><br>  }else if(state == AppLifecycleState.<strong class="markup--strong markup--pre-strong">suspending</strong>){<br>    // <strong class="markup--strong markup--pre-strong">app suspended (not used in iOS)</strong><br>  }<br>}</pre><p name="3212" id="3212" class="graf graf--p graf-after--pre">And… That is it, I hope you enjoy the article. Check the source code <a href="https://github.com/pedromassango/flutter_app_lifecycle" data-href="https://github.com/pedromassango/flutter_app_lifecycle" class="markup--anchor markup--p-anchor" rel="noopener" target="_blank">here</a>.