<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Greg Perry</title>
    <description>The latest articles on DEV Community by Greg Perry (@andrious).</description>
    <link>https://dev.to/andrious</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F125608%2Fa06f8011-6a91-449c-9a12-f7e68681d261.png</url>
      <title>DEV Community: Greg Perry</title>
      <link>https://dev.to/andrious</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/andrious"/>
    <language>en</language>
    <item>
      <title>StateX By Example</title>
      <dc:creator>Greg Perry</dc:creator>
      <pubDate>Tue, 29 Jul 2025 03:02:24 +0000</pubDate>
      <link>https://dev.to/andrious/statex-by-example-10o2</link>
      <guid>https://dev.to/andrious/statex-by-example-10o2</guid>
      <description>&lt;p&gt;&lt;em&gt;Learn StateX using its example app.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;StateX is a class found in the &lt;a href="https://pub.dev/packages/state_extended" rel="noopener noreferrer"&gt;state_extended&lt;/a&gt; package. It merely ‘extends’ the capabilities of Flutter’s State class with the addition of a Controller class, a built-in FutureBuilder, and a built-in InheritedWidget. This package was recently accepted by &lt;a href="https://fluttergems.dev/packages/state_extended/" rel="noopener noreferrer"&gt;Flutter Gems&lt;/a&gt; under the category, &lt;a href="https://fluttergems.dev/flutter-framework/" rel="noopener noreferrer"&gt;Flutter Framework&lt;/a&gt;. In this article, a review of what it can do for you will involve a walk through its accompanying &lt;a href="https://github.com/AndriousSolutions/state_extended/tree/master/example" rel="noopener noreferrer"&gt;example app&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Index of Topics
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;From The Start&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;First Class&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;A State of Control&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Build Better&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;The Three Count&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;A Separate State&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Inherited Performance&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Build Once And Forget It&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Less Is More&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Note The Change&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;It’s a Do-over&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;A New State&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Keep Control&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Keep Count&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Make A New Start&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Learn by Example&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;A Singular Approach&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;It’s All Timing&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Adaptive Abstraction&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Unknown Potential&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;The Many Constructs&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Handle Your Errors&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;A Better View&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Trouble From The Start&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;To Catch An Error&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;To Err Is Programming&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;To Build Or Not To Build&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Quick Reference&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;StateX Class&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;StateXController Class&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Initialization Handlers&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Event Handling&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Error Handler&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Presented in this article will be a series of screenshots conveying the example app’s source code. Each screenshot will be accompanied by one or more paragraphs explaining the function and features on display. Further, the screenshots’ captions will be linked to the very source code in its &lt;a href="https://github.com/AndriousSolutions/state_extended" rel="noopener noreferrer"&gt;Github repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let’s begin.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh3wd4qq3ex5mg71che99.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh3wd4qq3ex5mg71che99.png" width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://andrious.medium.com/my-medium-9de112c2d85c" rel="noopener noreferrer"&gt;Other Stories by Greg Perry&lt;/a&gt;



&lt;h3&gt;
  
  
  From The Start &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The first set of screenshots below starts with the &lt;strong&gt;main&lt;/strong&gt; () function. Not a hard-and-fast rule, but you’ll notice I use ‘export files’ to keep the number of import statements used to a more manageable nmber. Instead of reams of &lt;strong&gt;import&lt;/strong&gt; statements at the start of every Dart file, I followed the Dart team’s approach to &lt;a href="https://www.dartlang.org/guides/libraries/create-library-packages#organizing-a-library-package" rel="noopener noreferrer"&gt;organizing a library package&lt;/a&gt;. You can see the next two screenshots export the very files highlighted with red arrows in the first screenshot below. As a result, there’s only one import statement required for the &lt;strong&gt;main&lt;/strong&gt; () function (Tap the screenshots for a closer look).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F96swzfkiucs3df11w81m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F96swzfkiucs3df11w81m.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/main.dart" rel="noopener noreferrer"&gt;main.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjgs4gcd8c1cfwpf7a5i3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjgs4gcd8c1cfwpf7a5i3.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/src/view.dart" rel="noopener noreferrer"&gt;view.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftrr0fnoad0rtaz7z55fk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftrr0fnoad0rtaz7z55fk.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/src/controller.dart" rel="noopener noreferrer"&gt;controller.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  First Class &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;You can see it’s the &lt;em&gt;MyApp&lt;/em&gt; widget that’s called in the &lt;strong&gt;runApp&lt;/strong&gt;() function. That class is presented in the first screenshot below — and note only three import statements. Further down the library file, you’re introduced to the State class, &lt;em&gt;_MyAppState&lt;/em&gt; (second screenshot below). Here, we encounter the first class from the &lt;a href="https://pub.dev/packages/state_extended" rel="noopener noreferrer"&gt;state_extended&lt;/a&gt; package, &lt;em&gt;AppStateX&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2jygg5pxafa2bio9ykr2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2jygg5pxafa2bio9ykr2.png" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart" rel="noopener noreferrer"&gt;my_app.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc17pzxu0gzbdg3wpf4fi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc17pzxu0gzbdg3wpf4fi.png" width="800" height="707"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart#L29" rel="noopener noreferrer"&gt;my_app.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbwqphactlcfcy8dx9zhk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbwqphactlcfcy8dx9zhk.png" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part04_app_statex.dart#L14" rel="noopener noreferrer"&gt;part04_app_statex.dart.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  A State of Control &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In the second screenshot above, you can see how SOC’s are assigned to a State object. Generally, the State object worries about the interface, while those ‘State Object Controllers’ worry about everything else. In the last screenshot above, you can see that the AppStateX class even worries about Error Handling as well as activates its built-in InheritedWidget (more on that later). The AppStateX class is an extension of another class from the state_extended package called &lt;em&gt;StateX&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Build Better &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Of course, the AppStateX class has a &lt;strong&gt;build&lt;/strong&gt;() function, but you’re discouraged from using that function in your apps — not directly anyway. However, in this example app, I’ll use it to assign boolean values to Flutter’s development tools. The first screenshot below shows you how that’s done. The video demonstrates those tools. Further note in the first screenshot, the &lt;strong&gt;return&lt;/strong&gt; statement calls AppStateX’s own &lt;strong&gt;build&lt;/strong&gt;() function. In turn, that eventually calls the &lt;strong&gt;builder&lt;/strong&gt;() function (second screenshot) where additional ‘development tool’ values are taken in by the MaterialApp widget.&lt;/p&gt;

&lt;p&gt;You see, you’re to ignore the &lt;strong&gt;build&lt;/strong&gt;() function in a StateX object class. You would use the &lt;strong&gt;builder&lt;/strong&gt;() function instead to take full advantage of StateX’s functions and features. If you do use the &lt;strong&gt;build&lt;/strong&gt;() function, it’s then just like another State class.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2A8sVqTDg2ARZPI_GZdqGGzA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2A8sVqTDg2ARZPI_GZdqGGzA.gif" width="8" height="16"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu9a3xbfi7oz9ry2cwvv6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu9a3xbfi7oz9ry2cwvv6.png" width="800" height="692"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart#L71" rel="noopener noreferrer"&gt;my_app&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl1mvwtz5a88f07q117b9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl1mvwtz5a88f07q117b9.png" width="800" height="698"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart#L106" rel="noopener noreferrer"&gt;my_app&lt;/a&gt;



&lt;h3&gt;
  
  
  The Three Count &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The Page1 widget is presented to the user when the app starts up. The second screenshot below conveys the Controller objects instantiated for its State object, &lt;em&gt;Page1State&lt;/em&gt;. It’s the third screenshot that displays not one but three counters——each conceived in a different way.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm0cecalpk5v6v93buvz1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm0cecalpk5v6v93buvz1.png" width="800" height="685"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart#L114" rel="noopener noreferrer"&gt;my_app.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xdvjnzlkcfwnkv9a06j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xdvjnzlkcfwnkv9a06j.png" width="800" height="697"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L19" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg4nl67d5cafe2e5f76l2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg4nl67d5cafe2e5f76l2.png" width="800" height="642"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  A Separate State &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In the video below, the counter is incremented three times. Note, the &lt;strong&gt;Text&lt;/strong&gt; widget and the &lt;strong&gt;setBuilder&lt;/strong&gt;() function will increment, but the third counter residing in a separate StatefulWidget does not. Perfectly normal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiec03mhlhrvmz47pfgun.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiec03mhlhrvmz47pfgun.gif" width="600" height="1215"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcj1vat91dgalh8t208ln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcj1vat91dgalh8t208ln.png" width="800" height="715"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L164" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwv5zsn7u5ej2pesqbtj3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwv5zsn7u5ej2pesqbtj3.png" width="800" height="688"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part06_inherited_widget_state_mixin.dart#L22" rel="noopener noreferrer"&gt;part06_inherited_widget_state_mixin.dart&lt;/a&gt;



&lt;p&gt;As you know, in Flutter, a State object’s &lt;strong&gt;setState&lt;/strong&gt;() function will have its &lt;strong&gt;build&lt;/strong&gt;() function called again in the next frame cycle. The video above demonstrates this. The first screenshot above is the example app’s code in the &lt;strong&gt;builder&lt;/strong&gt;() function that’s run again and again with every press of the button. The second screenshot above is the inner workings of the StateX object. You can see it’s there where the &lt;strong&gt;builder&lt;/strong&gt;() function is called. Since the &lt;em&gt;_useInherited&lt;/em&gt; variable is set to false, the &lt;strong&gt;builder&lt;/strong&gt;() function is called every time. However, if the variable is set to true, the &lt;strong&gt;builder&lt;/strong&gt;() function is not called ever again! Let’s see how that works below.&lt;/p&gt;

&lt;h3&gt;
  
  
  Inherited Performance &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In the video below, things have changed. When you ‘turn on’ the built-in InheritedWidget (I’ll explain how that’s done shortly), the &lt;em&gt;_useInherited&lt;/em&gt; variable is set to true in the StateX object. The first screenshot below highlights what that means.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff64ldp2av5iu9hcyuupp.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff64ldp2av5iu9hcyuupp.gif" width="624" height="1264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi5h89chonjysdqeaw6tu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi5h89chonjysdqeaw6tu.png" width="800" height="688"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part06_inherited_widget_state_mixin.dart#L22" rel="noopener noreferrer"&gt;part06_inherited_widget_state_mixin.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyc0xp7ihem6n3hkw7zof.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyc0xp7ihem6n3hkw7zof.png" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L183" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  Build Once And Forget It &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;builder&lt;/strong&gt;() function is only called once and is then wrapped in the built-in InheritedWidget. That means that &lt;strong&gt;Text&lt;/strong&gt; widget will never be called and rebuilt again — it doesn’t increment with every push of the button anymore. You see, the whole screen is no longer rebuilt again and again. Do you follow? However, the other two counters do increment. That’s because they are both dependencies of the StateX object’s built-in InheritedWidget. Only those widgets are rebuilt in the interface making for better performance. This is nothing new in Flutter.&lt;/p&gt;

&lt;p&gt;In the second screenshot below, we see the &lt;strong&gt;setBuilder&lt;/strong&gt;() function is very much like the &lt;a href="https://api.flutter.dev/flutter/widgets/Builder-class.html" rel="noopener noreferrer"&gt;Builder&lt;/a&gt; widget supplies a BuildContext parameter and returns a widget. This function is from the Mixin found in the state_extended package called &lt;em&gt;InheritedWidgetStateMixin&lt;/em&gt;. We’ve been looking at its inner workings for some time now with its &lt;strong&gt;buildF&lt;/strong&gt;() function (first screenshot below), but now we’ll examine its &lt;strong&gt;setBuilder&lt;/strong&gt;() function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F03002boceosoqwll2h1x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F03002boceosoqwll2h1x.png" width="800" height="688"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part06_inherited_widget_state_mixin.dart#L22" rel="noopener noreferrer"&gt;part06_inherited_widget_state_mixin.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmlp0exteg6lzg5pcnozi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmlp0exteg6lzg5pcnozi.png" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part04_app_statex.dart#L386" rel="noopener noreferrer"&gt;part04_app_statex.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fki5vs9gvwdhnajd3j169.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fki5vs9gvwdhnajd3j169.png" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part04_app_statex.dart#L727" rel="noopener noreferrer"&gt;part04_app_statex.dart&lt;/a&gt;



&lt;p&gt;In the second screenshot above, we’re presented with the &lt;strong&gt;setBuilder&lt;/strong&gt;() function. Now you see why the counter is incremented whether the &lt;strong&gt;useInherited&lt;/strong&gt; getter returns true or false — the &lt;strong&gt;builder&lt;/strong&gt;() function is called in either case. Looking at the third screenshot, if set to true, the &lt;strong&gt;builder&lt;/strong&gt;() function is wrapped in the StatelessWidget, &lt;em&gt;StateDependentWidget&lt;/em&gt;. It is that widget that becomes a ‘dependent’ of the built-in InheritedWidget using the line:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;stateMixin?.dependOnInheritedWidget(context)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I’d say the most powerful feature of Flutter’s InheritedWidget is that whenever it’s called again, its dependency widgets will be rebuilt (their &lt;strong&gt;build&lt;/strong&gt;() functions called again). Nothing new here. It’s all Flutter.&lt;/p&gt;

&lt;p&gt;The third and final counter is also incremented. As you see in the first screenshot below, it’s the one encased in a StatefulWidget. Its State object is made an dependent on Page1State’s built-in InheritedWidget as well. In the third screenshot, it’s the Controller object’s &lt;strong&gt;buildThisState&lt;/strong&gt;() function that assigns this dependency.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff64ldp2av5iu9hcyuupp.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff64ldp2av5iu9hcyuupp.gif" width="624" height="1264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr7y63kpmkm3366lhqgfs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr7y63kpmkm3366lhqgfs.png" width="800" height="703"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L194" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8b14u4zwdkhcxps4kma8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8b14u4zwdkhcxps4kma8.png" width="800" height="699"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L357" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  Less Is More &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Let’s look at another example. Viewing the video below, know it is only the red ‘word pairs’ being rebuilt in set intervals — it’s the only portion of the screen changing every few seconds. That is the only portion of the screen being repainted. The rest of the screen is left untouched. The less the Widget tree is rebuilt, the better the overall performance. In the screenshot below, you see it's the getter, &lt;em&gt;wordPair&lt;/em&gt;, that supplies these word-pairs. I’ll show how this works next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnuwwciimv0li2nvduebs.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnuwwciimv0li2nvduebs.gif" width="560" height="1134"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftmse6fzsnqt0h2jxu7ep.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftmse6fzsnqt0h2jxu7ep.png" width="430" height="910"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh9qi446r4pw2a8en67kk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh9qi446r4pw2a8en67kk.png" width="800" height="703"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L164" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;p&gt;In the first screenshot below, the getter uses the &lt;strong&gt;SetBuilder&lt;/strong&gt; widget. This widget is also from the &lt;a href="https://pub.dev/packages/state_extended" rel="noopener noreferrer"&gt;state_extended&lt;/a&gt; package. It involves the App State object’s &lt;em&gt;dataObj&lt;/em&gt; property. It’s of type &lt;em&gt;object&lt;/em&gt;, and so you can pass ‘anything’ down the Widget tree. In the case of this example app, it’s a String object that is passed down. See the second screenshot below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwxhzgmc9e2kzibgcvi8c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwxhzgmc9e2kzibgcvi8c.png" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/word_pair_timer.dart#L162" rel="noopener noreferrer"&gt;word_pair_timer.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftf9v3ubcu1rp4e1zh66g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftf9v3ubcu1rp4e1zh66g.png" width="800" height="700"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart#L30" rel="noopener noreferrer"&gt;my_app.dart&lt;/a&gt;



&lt;p&gt;The &lt;strong&gt;SetBuilder&lt;/strong&gt; widget rebuilds when that String object changes in value. In the first screenshot below, that occurs when a new word-pair is assigned. Finally, the setter, &lt;em&gt;dataObject&lt;/em&gt;, calls the AppStateX’s InheritedWidget with the &lt;strong&gt;notifyClients&lt;/strong&gt; () function. Doing so, will rebuild any and all &lt;strong&gt;SetBuilder&lt;/strong&gt; widgets — in fact, any widget set as a dependency to the AppStateX’s InheritedWidget. Makes for an efficient interface.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdd8xwii2pnzouz3mdl3p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdd8xwii2pnzouz3mdl3p.png" width="800" height="702"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/word_pair_timer.dart#L185" rel="noopener noreferrer"&gt;word_pair_timer.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbs39va5rpjj1uvkly26l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbs39va5rpjj1uvkly26l.png" width="800" height="692"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part17_app_state_mixin.dart#L22" rel="noopener noreferrer"&gt;part17_app_state_mixin.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  Note The Change &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Finally, the video below demonstrates what happens with the three counters when selecting the Switch, ‘Use built-in ChangNotifier.’ All three counters now increment. It’s easy enough to understand the first two. We’ve returned to rebuilding the whole interface again. Both the &lt;strong&gt;Text&lt;/strong&gt; widget and &lt;strong&gt;setBuilder&lt;/strong&gt;() function will rebuild, but why would the third counter in its separate StatefulWidget? It shouldn’t increment — it’s no longer dependent on an InheritedWidget?! That’s because it’s become a &lt;em&gt;Listener&lt;/em&gt;. State Object Controllers have a built-in &lt;a href="https://api.flutter.dev/flutter/foundation/ChangeNotifier-class.html" rel="noopener noreferrer"&gt;&lt;em&gt;ChangeNotifier&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnb8sc8ui4on97ss7fu6o.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnb8sc8ui4on97ss7fu6o.gif" width="560" height="1134"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe17n72pp3k5p0slxos4p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe17n72pp3k5p0slxos4p.png" width="800" height="703"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/controller.dart#L151" rel="noopener noreferrer"&gt;controller.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpaatxt8mg9jfk0qjj6h3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpaatxt8mg9jfk0qjj6h3.png" width="800" height="698"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part12_rebuild_controller_states_mixin.dart#L53" rel="noopener noreferrer"&gt;part12_rebuild_controller_states_mixin.dart&lt;/a&gt;



&lt;p&gt;In the first screenshot above, you can see the Controller’s &lt;strong&gt;buildThisState&lt;/strong&gt;() function will also include Page1’s State object as a ‘State Listener’ if the variable, &lt;em&gt;useChangeNotifier&lt;/em&gt;, is set to true. That’s exactly what happens in the video above.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rebuild = addStateListener(state);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In the second screenshot above, you can see the State object’s &lt;strong&gt;setState&lt;/strong&gt;() function is called when that Listener is notified. They’re notified through the Controller which had added them. This is done in the Controller’s version of the &lt;strong&gt;setState&lt;/strong&gt;() function. Note, in the first screenshot below, its &lt;strong&gt;setState&lt;/strong&gt;() function also includes notifying any Listeners:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;notifyListeners();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The next two screenshots trace back to Flutter’s own &lt;a href="https://api.flutter.dev/flutter/foundation/ChangeNotifier-class.html" rel="noopener noreferrer"&gt;&lt;em&gt;ChangeNotifier&lt;/em&gt;&lt;/a&gt;class calling its &lt;strong&gt;notifyListeners&lt;/strong&gt;() function and ‘rebuilding’ any and all State objects assigned. See how that works? Just another way of accessing and rebuilding dispersed and remote State objects — via a State Object Controller.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn4mxlap63o3clbkxa44l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn4mxlap63o3clbkxa44l.png" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part02_statex_controller.dart#L145" rel="noopener noreferrer"&gt;part02_statex_controller.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl0ggf9ps5e5pwj0pfviz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl0ggf9ps5e5pwj0pfviz.png" width="800" height="707"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part12_rebuild_controller_states_mixin.dart#L102" rel="noopener noreferrer"&gt;part12_rebuild_controller_states_mixin.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo1jzg6gewu4a2zpr8vcw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo1jzg6gewu4a2zpr8vcw.png" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part12_rebuild_controller_states_mixin.dart#L148" rel="noopener noreferrer"&gt;part12_rebuild_controller_states_mixin.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  It’s a Do-over &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;To activate its built-in InheritedWidget, a StateX object must be instantiated with the formal parameter, &lt;em&gt;useInherited&lt;/em&gt;, set to true. Notice in the video below, there’s a distinct ‘refresh’ of the screen when the Switch, &lt;em&gt;Use built-in InheritedWidget&lt;/em&gt;, is tapped on. That’s because the App’s whole interface is rebuilt again. Note, it’s also rebuilt again with every change of those Development tools settings introduced earlier. The App’s interface is rebuilt when demonstrating much of this example app’s functionality. That means the &lt;em&gt;MaterialApp&lt;/em&gt; widget in this example app is being called again and again (see the second screenshot below). Let’s how that’s done.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff64ldp2av5iu9hcyuupp.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff64ldp2av5iu9hcyuupp.gif" width="624" height="1264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkufir23rhhnbrbr0t9zs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkufir23rhhnbrbr0t9zs.png" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L18" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3yluce5pakuw7r57u7y6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3yluce5pakuw7r57u7y6.png" width="800" height="699"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart#L106" rel="noopener noreferrer"&gt;my_app.dart&lt;/a&gt;



&lt;p&gt;In the first screenshot below, selecting the Switch calls the Controller’s method, &lt;strong&gt;onChangedInherited&lt;/strong&gt;(). Two things need to happen to then activate the StateX object’s built-in InheritedWidget: the whole app interface must be rebuilt and that particular StateX object must be recreated.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fge5n4hcpbem0pwdl9hi4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fge5n4hcpbem0pwdl9hi4.png" width="800" height="700"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L247" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fib8nc2rlbba461r080ku.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fib8nc2rlbba461r080ku.png" width="800" height="697"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/controller.dart#L90" rel="noopener noreferrer"&gt;controller.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  A New State &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In Flutter, State objects are recreated when their Statefulwidget is assigned a ‘new’ Key value. In the second screenshot above, that’s accomplished with the line, page1Key = null;. Again, nothing new here. This is how Flutter works. The second thing to do is simply rebuild the App’s State object:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;appState?.setState((){});&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Every Controller has a reference for the App’s State object. In the first screenshot below, we see the App’s State object’s &lt;strong&gt;builder&lt;/strong&gt;() function called again. Again, changing any Development tool settings introduced earlier requires the line, appState?.setState((){});.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkevc9rgda8naen7a9mhg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkevc9rgda8naen7a9mhg.png" width="800" height="707"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart#L106" rel="noopener noreferrer"&gt;my_app.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7psv1lefzh429xxmyry6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7psv1lefzh429xxmyry6.png" width="800" height="699"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L9" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F77a1ql463jckpo1ual39.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F77a1ql463jckpo1ual39.png" width="800" height="695"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/controller.dart#L11" rel="noopener noreferrer"&gt;controller.dart&lt;/a&gt;



&lt;p&gt;In the second screenshot above is the StatefulWidget, &lt;em&gt;Page1&lt;/em&gt;. Note, if not explicitly provided one, its Key value is supplied by the screen’s Controller, Controller().page1Key. Remember, however, it was set to &lt;strong&gt;null&lt;/strong&gt; with a tap of a Switch. This means the Key value stored in the class property, _page1Key, has now changed to a completely new value. In Flutter, this causes the State object to be recreated. Being recreated, the value passed to this new State object is now set to true: &lt;strong&gt;Controller&lt;/strong&gt;().useInherited&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep Control &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;If you haven’t noticed by now, each State Object Controller class in the example app uses a factory constructor to instantiate only one instance of each class. Three of those classes are conveyed in the screenshots below.&lt;/p&gt;

&lt;p&gt;Again, not a hard-and-fast rule, but I’ve found keeping only one instance of the State Object Controllers has proven well-suited for their role: A class object representing the ‘ongoing state’ of the app in a singular instance. An example of this, of course, is the running count that’s displayed. Its ‘interface settings’ is also maintained by a Controller. Further advantages in using this Singleton Pattern will be explained shortly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk4yss2mspgmertfrsg2k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk4yss2mspgmertfrsg2k.png" width="800" height="690"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/controller.dart#L11" rel="noopener noreferrer"&gt;controller.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwgw1l81winf1vkxe0ogk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwgw1l81winf1vkxe0ogk.png" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/word_pair_timer.dart#L1" rel="noopener noreferrer"&gt;word_pair_timer.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdj3bddnboowthpxbbgq3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdj3bddnboowthpxbbgq3.png" width="800" height="702"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/controller/example_app_controller.dart#L11" rel="noopener noreferrer"&gt;example_app_controller.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  Keep Count &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Since it’s a complete recreation of the State object and its counter property, count, we will have to save the count before the switch. Of course, the Controller object will take care of all of this. In the first screenshot below, using its &lt;strong&gt;stateInit&lt;/strong&gt;(State state) function, a controller can determine the StateX object it’s currently working with, and in this case, supply the count to the new screen. Otherwise, after the switch, you would just see zeros. Makes sense?&lt;/p&gt;

&lt;h3&gt;
  
  
  Make A New Start &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Note, the video below further demonstrates this ‘rebuilding of the App’ with the line, appState?.setState((){});.In the video, you see the ‘debug banner’ is turned off and then changing the app’s whole theme from &lt;em&gt;Material3&lt;/em&gt; to &lt;em&gt;Material2&lt;/em&gt;. Both required a new call to the App’s MaterialApp widget.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F20ylsl7r2njfxui7yz7g.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F20ylsl7r2njfxui7yz7g.gif" width="80" height="162"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmwwvgedm5tdcgfzv78dn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmwwvgedm5tdcgfzv78dn.png" width="800" height="703"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/controller.dart#L64" rel="noopener noreferrer"&gt;controller.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdl1ytfm02ucu4dx5ry69.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdl1ytfm02ucu4dx5ry69.png" width="800" height="692"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L43" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  Learn by Example &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This is a ‘demonstration’ app as well. And so, as you see in the second screenshot above, the Page1 State object’s &lt;strong&gt;initState&lt;/strong&gt; () function has many examples of how this &lt;a href="https://pub.dev/packages/state_extended" rel="noopener noreferrer"&gt;state_extended&lt;/a&gt; package empowers you to make versatile and adaptive code by giving you more than one way to retrieve a State object that makes up your App from anywhere at anytime.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Singular Approach &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;By the way, another reason for the Singleton Pattern used by instantiating all the State Object Controllers with a factory constructor is to take advantage of the versability and readability that’s achieved. You can then make any number of construction calls necessary to perform specific tasks throughout the app. An example of this is next.&lt;/p&gt;

&lt;h3&gt;
  
  
  It’s All Timing &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;As you many know, it was the WordPairsTimer controller that was providing those red ‘word pairs’ at set intervals using its getter, &lt;em&gt;wordPair&lt;/em&gt;. In the first screenshot below, you see this controller follows the Singleton pattern. In the second screenshot below, it’s instantiated as one of the controllers to work with the first screen, &lt;em&gt;Page1State&lt;/em&gt;, displaying the word-pairs.&lt;/p&gt;

&lt;p&gt;However, this App has a &lt;a href="https://api.flutter.dev/flutter/material/Drawer-class.html" rel="noopener noreferrer"&gt;Drawer&lt;/a&gt; widget, and whenever it opens, I want to turn off the Timer that’s changing the word-pairs every 5 seconds. The ‘easiest’ means to do this is presented in the third screenshot below — just call the constructor again. The Singleton pattern approach makes this possible.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwgw1l81winf1vkxe0ogk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwgw1l81winf1vkxe0ogk.png" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/word_pair_timer.dart#L1" rel="noopener noreferrer"&gt;word_pair_timer.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcn21qknqyv5gju38badb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcn21qknqyv5gju38badb.png" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L18" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3glbus51w8r3ppypxaqw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3glbus51w8r3ppypxaqw.png" width="800" height="698"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart#L113" rel="noopener noreferrer"&gt;my_app.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  Adaptive Abstraction &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Those construction calls for the WordPairsTimer controller right there in the first page was more for the benefit of the reader. In truth, I would normally only reference the State object’s controller, &lt;em&gt;con&lt;/em&gt;, throughout that interface. This would then incorporate a layer of abstraction to the app. You can see an example of this in the first screenshot below. The interface has no business knowing there’s a word-pair timer running somewhere, and is turned off just before the Drawer is opened. See what I changed I made in the first screenshot below to achieve this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fboi3ukot71s2mdedam03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fboi3ukot71s2mdedam03.png" width="800" height="693"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart#L113" rel="noopener noreferrer"&gt;my_app.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1al2e3lc1i7kjgzjlb6e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1al2e3lc1i7kjgzjlb6e.png" width="800" height="689"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/controller/example_app_controller.dart#L162" rel="noopener noreferrer"&gt;example_app_controller.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F025lknheij3hlf2qmb8n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F025lknheij3hlf2qmb8n.png" width="800" height="695"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/controller.dart#L158" rel="noopener noreferrer"&gt;controller.dart&lt;/a&gt;



&lt;p&gt;The second screenshot above is of the App’s State object controller, &lt;em&gt;ExampleAppController&lt;/em&gt;. You see the new &lt;strong&gt;onOpenDrawer&lt;/strong&gt;() and &lt;strong&gt;onCloseDrawer&lt;/strong&gt;() functions. They, in turn, call their counterparts found in the Controller class. Finally, we see those functions, in the third screenshot above, calling the original methods found in the WordPairsTimer controller. See how that works?&lt;/p&gt;

&lt;h3&gt;
  
  
  Unknown Potential &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Back on the interface side, there’s no hint of what’s going on when the Drawer callback functions fire (see first screenshot below). The WordPair Timer process could be modified down the road or removed outright without changing one bit of the interface. It’s the use of these State Object Controllers that provides this layer of abstraction and makes your code that much more adaptive and its maintenance that much easier.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Many Constructs &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The second screenshot below conveys another example of using multiple constructor calls from the same class. We’re back setting the built-in InheritedWidget on or off with the controller property, &lt;em&gt;useInherited&lt;/em&gt;, for the Page 1 screen. Note the readability. Flutter doesn’t allow dynamic instance variables in the class. The &lt;a href="https://dart.dev/language/constructors#use-an-initializer-list" rel="noopener noreferrer"&gt;initializer list&lt;/a&gt; can only initialize instance variables before the constructor body runs. and so this a more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9fa5g53dvz5a1qe8qv2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9fa5g53dvz5a1qe8qv2.png" width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart#L122" rel="noopener noreferrer"&gt;my_app.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa4ha97larw5l9vn63ff0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa4ha97larw5l9vn63ff0.png" width="800" height="640"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L18" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  Handle Your Errors &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;You hope for no errors in your app. However, your app will error. You have to prepare for this fact. The StateX package allows you to prepare for this fact whether they're unexpected errors or anticipated errors at times. Maybe there’s a case where intermittent errors are known to occur in your app — a network drop is known to occur, for example. In certain cases, a process is known to fail. This package gives the means to acknowledge such errors and shut down gracefully if not actually overcome the error and continue running.&lt;/p&gt;

&lt;p&gt;As an example, in the video below, the app intentionally throws an anticipated error with every push of the counter button (see screenshot below). This example app logs many of the events that occur while running, and you can see the error is recognized in the second screenshot. An &lt;strong&gt;onError&lt;/strong&gt;() method fires in a series of State objects all the way back to the App’s State object, &lt;em&gt;_MyAppState&lt;/em&gt;. One of those methods actually recovers from this Exception by incrementing the count regardless.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpxtoq60a0hq0570eqnhx.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpxtoq60a0hq0570eqnhx.gif" width="600" height="1215"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx48tp5mocuryd1eyajpz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx48tp5mocuryd1eyajpz.png" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L291" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy8izlchavtak8wjy5qvf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy8izlchavtak8wjy5qvf.png" width="509" height="1041"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In truth, it is the App’s State object, &lt;em&gt;_MyAppState&lt;/em&gt;, that catches the error. It then begins a series of &lt;strong&gt;onError&lt;/strong&gt;() function calls. It first calls the State object where the error likely originated. When such a State object is found, its Controllers’ &lt;strong&gt;onError&lt;/strong&gt;() methods are called first before calling its &lt;strong&gt;onError&lt;/strong&gt;() method. It is the App’s State object that finally records and logs the error.&lt;/p&gt;

&lt;p&gt;Back to our example, the third screenshot below highlights when an &lt;strong&gt;onError&lt;/strong&gt;() method in one of the Controllers recognizes the error and increments the counter regardless. A very simple example, but you get the idea.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fohc6u807k7cqpj1yb5a2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fohc6u807k7cqpj1yb5a2.png" width="800" height="694"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part04_app_statex.dart#L14" rel="noopener noreferrer"&gt;part04_app_statex.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft11dh4fguu6qmze4yvmh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft11dh4fguu6qmze4yvmh.png" width="800" height="687"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part04_app_statex.dart#L433" rel="noopener noreferrer"&gt;part04_app_statex.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffx4djc7yzhklyyk85xu5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffx4djc7yzhklyyk85xu5.png" width="800" height="657"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/controller.dart#L244" rel="noopener noreferrer"&gt;controller.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  A Better View &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This is not a built-in feature of the state_extended package, but a further demonstration of how to seamlessly implement a feature using a State Object Controller. Instead of the ‘Red Screen of Doom’ that comes with errors while developing in Flutter, how about a more useful, more pleasant-looking error screen? The BuildErrorWidget class integrates such a screen by merely introducing it as a controller to the App’s State object. In the video below, the class allows you to control its use and returns to the original error screen when appropriate while developing, while testing, and while running in production.&lt;/p&gt;

&lt;p&gt;The video below demonstrates this with an error explitcity thrown when going to Page 2 in the example app. You’re able to manually ‘trip errors’ in this example app to demonstrate this package’s error handling. In the video, you see the traditional ‘Red Screen of Doom.’ However, when the ‘Custom Error Screen’ is switched on, the BuildErrorWidget class will assign a custom builder to Flutter’s &lt;a href="https://api.flutter.dev/flutter/widgets/ErrorWidget/builder.html" rel="noopener noreferrer"&gt;&lt;strong&gt;ErrorWidget.builder&lt;/strong&gt;&lt;/a&gt; callback. Now, when such an error occurs, a more helpful error screen is displayed when the intended widget fails to build. Very nice.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2AdQ5pimFp6yQRRrBUkJAhdA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2AdQ5pimFp6yQRRrBUkJAhdA.gif" width="8" height="16"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvqzrjtc5fnn4d2y8mw8b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvqzrjtc5fnn4d2y8mw8b.png" width="800" height="707"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart#L29" rel="noopener noreferrer"&gt;my_app.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F50el3pnmivnllw2yuhak.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F50el3pnmivnllw2yuhak.png" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/common/controller/build_error_widget.dart#L172" rel="noopener noreferrer"&gt;build_error_widget.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  Trouble From The Start &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The video below throws an error right at the start of the app — in the AppStateX’s &lt;strong&gt;initAsync&lt;/strong&gt;() function. It’s usually at startup when things have trouble — more of an effort may be needed to start successfully. In the video, the example app starts up without incident. However, the app is repeatedly restarted with specific settings switched on to show what the package can do for you if and when your app encounters an error right at startup.&lt;/p&gt;

&lt;p&gt;The ‘Error initAsync() at Startup’ switch is first turned on. When the app starts up again, you are greeted by the good ol’ ‘Red Screen of Boom!’ Nothing left for you to do but try the app again. Happily, you’re able to get into the app again because it actually ‘recovers’ this time. A snackbar appears with the message, ‘An error at startup, but was caught.’ Going back to the Settings screen, you’ll notice the ‘Catch Error’ option is set, Yes. However, in the video, it is set back to ‘No’ so to again demonstrate the custom error screen with another restart. Again, you can’t continue as the app has once again failed at startup, and you’re presented with an error screen. That’s ok. That’s because the app will catch the error the next time it starts up. The error is overcome once again. Let’s see how.&lt;/p&gt;

&lt;p&gt;This video emulates, for example, when the network is down at startup or when it fails to access some critical web service at startup. The app can’t continue — unless it can. That’s where the &lt;strong&gt;catchAsyncError&lt;/strong&gt;() function comes in (see the second screenshot below). The &lt;strong&gt;catchAsyncError&lt;/strong&gt;() function below looks out for an error message containing the string, ‘Error in App’s initAsync()!’ It then acts accordingly. If this function returns &lt;em&gt;false&lt;/em&gt;, the error is not successfully caught, it has failed to recover, and so an error screen is presented. Note, when not caught, the property, &lt;em&gt;catchInitAppAsyncError&lt;/em&gt;, is set to true for next time. Otherwise, the app will never start up successfully. Smart thinking.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2ABEK3wvrboL6ehoTere5xMQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2ABEK3wvrboL6ehoTere5xMQ.gif" width="1024" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzlb7prp9fs52bouakr46.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzlb7prp9fs52bouakr46.png" width="800" height="694"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part05_futurebuilder_state_mixin.dart#L23" rel="noopener noreferrer"&gt;part05_futurebuilder_state_mixin.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb8tvakz1xj56wx50lm9k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb8tvakz1xj56wx50lm9k.png" width="800" height="700"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/controller/example_app_controller.dart#L132" rel="noopener noreferrer"&gt;example_app_conroller.dart&lt;/a&gt;



&lt;p&gt;The first screenshot is of &lt;a href="https://pub.dev/packages/state_extended" rel="noopener noreferrer"&gt;state_extended&lt;/a&gt; package itself. It’s a snapshot of the &lt;strong&gt;build&lt;/strong&gt;() function called by the StateX class. Highlighted is the &lt;strong&gt;catchAsyncError&lt;/strong&gt;() function call. Your &lt;strong&gt;initAsync&lt;/strong&gt;() function has thrown an error, but you’re given an opportunity to possibly recover from the error with the &lt;strong&gt;catchAsyncError&lt;/strong&gt;() function.&lt;/p&gt;

&lt;p&gt;Of course, always returning true and freely ignoring errors would not be advisable. Such decisions will very likely only make your App fail further. It’s for those exceptions where a recovery may be possible or, at the very least, an opportunity to clean up resources and prevent any data corruption before bringing the crash to a ‘soft landing’ and have the app fail gracefully.&lt;/p&gt;

&lt;h3&gt;
  
  
  To Catch An Error &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In the next video below, you have the means to throw an error when attempting to open Page 2 in the example app. Again, the custom error screen is first demonstrated. However, it’s the ‘Catch Error’ option that’s of interest here. When that is switched on, the &lt;strong&gt;catchAyncError&lt;/strong&gt;() function in the second screenshot below will ‘catch’ the error and return true.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2A4vTdiJk1PR8qdMjmcn-yHg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2A4vTdiJk1PR8qdMjmcn-yHg.gif" width="8" height="16"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fevwc2ullwoijv3t7hl0y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fevwc2ullwoijv3t7hl0y.png" width="800" height="707"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/another_controller.dart#L61" rel="noopener noreferrer"&gt;another_controller.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftvq36l14dd1wcfxg4ogn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftvq36l14dd1wcfxg4ogn.png" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/another_controller.dart#L89" rel="noopener noreferrer"&gt;another_controller.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  To Err Is Programming &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This example app has &lt;em&gt;throw&lt;/em&gt; statements throughout its code. Again, this is to demonstrate this package’s ability to effectively handle errors. Another example is when the ‘Error in Builder’ is switched on. The first screenshot below shows an Exception being thrown. This simulates a Widget failing to be created in a &lt;strong&gt;build&lt;/strong&gt;() function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2ArC-1EQb-nd_lm5NzliYnIg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2ArC-1EQb-nd_lm5NzliYnIg.gif" width="8" height="16"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F72mxulai5nwyp8tys0ue.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F72mxulai5nwyp8tys0ue.png" width="800" height="702"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_02.dart#L123" rel="noopener noreferrer"&gt;page_02.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1csn3rjmy4ehnve8q9po.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1csn3rjmy4ehnve8q9po.png" width="800" height="693"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/common/controller/build_error_widget.dart#L236" rel="noopener noreferrer"&gt;build_error_widget.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  To Build Or Not To Build &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;As you know now, any Asynchronous operations that may fail in the &lt;strong&gt;initAsync&lt;/strong&gt;() function may be caught by the &lt;strong&gt;catchAsyncError&lt;/strong&gt;() function. However, an error in a &lt;strong&gt;build&lt;/strong&gt;() function can not be explicitly caught. No, if your &lt;strong&gt;build&lt;/strong&gt;() function fails, it’s an error that should *not* happen in production. It’s an error, it will be recorded and logged, but it is not recoverable. Of course, it’s your app, you can address such errors right in your &lt;strong&gt;build&lt;/strong&gt;() function and maybe even recover from it yourself — there’s just no ready means in the StateX class.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick Reference  &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  StateX Class &lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;.appStateX → Retrieves the App's appStateX object. Returns null if not available.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/appStateX.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.controller → Retrieves the State object's 'current' Controller.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/controller.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.deactivated → True if deactivated() was called.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/deactivated.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.disposed → True if disposed() was called.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/disposed.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.firstBuild → True if build() not called or called once.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/disposed.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.hiddenAppLifecycle → True if State object was in a 'hidden' state.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/hiddenAppLifecycle.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.identifier → Unique Srtring identifier foe this StsteX object.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/identifier.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.inactiveAppLifecycle → True if the State object was in an inactive state.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/inactiveAppLifecycle.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.isLastState → True if it's the 'latest' StateX object created in the app.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/isLastState.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.lastSystemEvent → Records the last system event called.StateX  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;didChangeAccessibilityFeatures
&lt;/li&gt;
&lt;li&gt;didChangeLocales
&lt;/li&gt;
&lt;li&gt;didChangeMetrics
&lt;/li&gt;
&lt;li&gt;didChangePlatformBrrightness
&lt;/li&gt;
&lt;li&gt;didChangeTextScalFactor
&lt;/li&gt;
&lt;li&gt;didHaveMemoryPressuure
&lt;/li&gt;
&lt;li&gt;didRequestAppExit&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;.pausedAppLifecycle&lt;/strong&gt; → True if State object was in a paused state.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/pausedAppLifecycle.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.resumedAppLifecycle&lt;/strong&gt; → True if State object was in a resumed state.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/resumedAppLifecycle.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;add&lt;/strong&gt;() → Add a Controller to this StateX object.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/addAll.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;addAll&lt;/strong&gt;() → Add a list of Controllers to be associated with this StateX object.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/addAll.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;stateByType&lt;/strong&gt;() → Retrieves another State object by its type. Returns null if not found.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/MapOfStateXsMixin/stateByType.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;stateById&lt;/strong&gt; () → Retrieve another State object using its unique String identifier. Returns null if not found.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/MapOfStateXsMixin/statesById.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;controllerByType&lt;/strong&gt; () → Retrieves one of its Controllers by their type.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/controllerByType.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;controllerById&lt;/strong&gt; () → Retrieves one of its Controllers by their unique String identifier.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/controllerById.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  StateXController Class &lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;.state → Returns current State object.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/SetStateMixin/state.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.statex → Retrieves current StateX object.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/statex.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.appStateX → References the App's State object.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/appStateX.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.initStateCalled→ True if initState() was already called.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/initStateCalled.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;activateState&lt;/strong&gt; () → Called when this State object is reinserted into the Widget tree after having been removed by deactivate().&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/SetStateMixin/state.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;addState&lt;/strong&gt; () → Associate this Controller to the specified State object. Returns the State Object's unique String identifier.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/addState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;deactivateState&lt;/strong&gt; () → Called whenever the State object was removed from the Widget tree. Passes the 'current' State object parameter.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/deactivateState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;disposeState&lt;/strong&gt; (covariant State state) → The supplied State object will never build again and taken into Flutter's garbage collection.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/disposeState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;initAsyncState&lt;/strong&gt; (covariant State state) → Called with every StateX associated qith this Controller initializing any 'time-consuming' operations needed done at startup.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/initAsyncState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ofState&lt;/strong&gt; )() → Retrieves a currently associated State object by its type T. Returns null if not found.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/SetStateMixin/ofState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;stateOf&lt;/strong&gt; () → Retrieves an associated State object by its StatefulWidget. Returns null if not found.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/SetStateMixin/stateOf.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Initialization Handlers &lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;initAsync&lt;/strong&gt; () → Initialize any 'time-consuming' operations at the beginning. Implement any asynchronous operations needed done at start up.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/initAsync.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/initAsync.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;initAsyncState&lt;/strong&gt; () → Called with every StateX associated with this Controller Initialize any 'time-consuming' operations at the beginning. Implement any asynchronous operations needed done at start up.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/initAsyncState.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/initAsyncState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;initState&lt;/strong&gt; () → Initialize anything necessary at the beginning. Implement any asynchronous operations needed done at start up.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/initState.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/initState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;runInitAsync&lt;/strong&gt; () → Call initAsync() all the time if returns true. Conditional calls initAsync() creating a Future with every rebuild&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/runInitAsync.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/runInitAsync.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Event Handling &lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;activate&lt;/strong&gt; () → Called when the State object is reinserted into the Widget tree.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/activate.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/activate.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;deactivate&lt;/strong&gt; () → Called when the State object is removed from the Widget tree.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/deactivate.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/deactivate.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;dependOnInheritedWidget&lt;/strong&gt; () → Link a widget to the StateX Object's InheritedWidget.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/InheritedWidgetStateMixin/dependOnInheritedWidget.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/dependOnInheritedWidget.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;detachedAppLifecycleState&lt;/strong&gt; () → The Flutter engine has detached the app from view and is shutting down.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/detachedAppLifecycleState.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/detachedAppLifecycleState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didChangeAccessibilityFeatures&lt;/strong&gt; () → Called when the current accessibility features have been changed.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didChangeAccessibilityFeatures.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didChangeAccessibilityFeatures.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didChangeDependencies&lt;/strong&gt; () → Called immediately after initState() or when a widget dependent on an InheritedWidget is to be rebuilt.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didChangeDependencies.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didChangeDependencies.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didChangeLocales&lt;/strong&gt; () → Called when the device's locale has changed.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didChangeLocales.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didChangeLocales.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didChangeMetrics&lt;/strong&gt; () → Called when the app's UI dimensions change. E.g. when a phone is rotated.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didChangeMetrics.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didChangeMetrics.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didChangePlatformBrightness&lt;/strong&gt; () → When the device's brightness has changed.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didChangePlatformBrightness.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didChangePlatformBrightness.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didChangeTextScaleFactor&lt;/strong&gt; () → Called when the platform's text scale changes.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didChangeTextScaleFactor.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didChangeTextScaleFactor.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didHaveMemoryPressure&lt;/strong&gt; () → Called when the system is running low on memory.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didHaveMemoryPressure.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didHaveMemoryPressure.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didPop&lt;/strong&gt; () → Called when this State is popped off a route.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didPop.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didPop.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didPopNext&lt;/strong&gt; () → The top route has been popped off returning this State object.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didPopNext.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didPopNext.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didPopRoute&lt;/strong&gt; () → Called when the app pops the current route. E.g. On Android, called when the back button is presse.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didPopRoute.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didPopRoute.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didPush&lt;/strong&gt; () → Called when this State is first pushed as a Route by a Navigator.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didPush.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didPush.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didPushNext&lt;/strong&gt; () → New route has been pushed, and this State object's route is no longer current.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didPushNext.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didPushNext.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didPushRouteInformation&lt;/strong&gt; () → Called when the application pushes a new RouteInformation and a restoration state onto the router.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didPushRouteInformation.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didPushRouteInformation.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didRequestAppExit&lt;/strong&gt; () → Called when a request is received from the system to exit the app. Exiting the app can proceed with [AppExitResponse.exit] response, and do not exit with [AppExitResponse.cancel] response.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didRequestAppExit.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didRequestAppExit.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didUpdateWidget&lt;/strong&gt; () → Called when the State object's StatefulWidget is recreated.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didUpdateWidget.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didUpdateWidget.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;dispose&lt;/strong&gt; () → Called when the [StateX] object will never build again and will be taken into Flutter's garbage collection.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/dispose.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/dispose.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;handleCancelBackGesture&lt;/strong&gt; () → Called when a predictive back gesture is canceled indicating that no navigation should occur.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/handleCancelBackGesture.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/handleCancelBackGesture.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;handleCommitBackGesture&lt;/strong&gt; () → Called when a predictive back gesture is finished successfully indicating that the current route should be popped.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/handleCommitBackGesture.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/handleCommitBackGesture.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;hiddenAppLifecycleState&lt;/strong&gt; () → The app is about to be paused (on iOS and Android), or has been minimized (Windows) or is no longer visible (on the web).&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/hiddenAppLifecycleState.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/hiddenAppLifecycleState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;inactiveAppLifecycleState&lt;/strong&gt; () → The app is in an inactive state and is not receiving user input.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/inactiveAppLifecycleState.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/inactiveAppLifecycleState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;pausedAppLifecycleState&lt;/strong&gt; () → The application is not currently visible to the user, not responding to user input, and running in the background.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/pausedAppLifecycleState.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/pausedAppLifecycleState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;reassemble&lt;/strong&gt; () → Called when the app is reassembled during development, E.g. A hot reload.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/reassemble.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/reassemble.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;resumedAppLifecycleState&lt;/strong&gt; () → The app has returned from the background. Is now visible and ready for user input.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/resumedAppLifecycleState.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/resumedAppLifecycleState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;setState&lt;/strong&gt; () → Call build() function of the State object in the next frame cycle.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/setState.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/setState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;updateShouldNotify&lt;/strong&gt; () → As a dependency of an InheritedWidget, return true to rebuild the State object.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/updateShouldNotify.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/updateShouldNotify.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Error Handler &lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;onError&lt;/strong&gt; () &lt;strong&gt;→&lt;/strong&gt; Offer an error handler&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXonErrorMixin/onError.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/onError.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;onAsyncError&lt;/strong&gt; () &lt;strong&gt;→&lt;/strong&gt; In case the initAsync() function has failed in error. This must be handled too. &lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/onAsyncError.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/onAsyncError.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;catchAsyncError&lt;/strong&gt; () &lt;strong&gt;→&lt;/strong&gt; Catch it if &lt;strong&gt;initAsync&lt;/strong&gt; () throws an error. Return true to indicate the error handled. Return false to continue the error handling StateX|StateXController&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Next article will cover the following topics:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Event Handling
&lt;/h3&gt;

&lt;p&gt;Remember, if not addressed, the example app's Timer will always be running taking up valuable CPU cycles even when those red Wordpairs are no longer in view. There are event handlers available to the StateX class to address such considerations. The screenshots below and see the Timer is actually terminated when moving off Page 1. Nice.&lt;br&gt;
The &lt;strong&gt;didPushNext&lt;/strong&gt;() method is called when the 'next route' is pushed from this current State object. Note, the _&lt;strong&gt;cancelTimer&lt;/strong&gt;() is called terminating the Timer before the Page 2 screen is displayed. Also, if there's an error, you can see the Timer is terminated in the &lt;strong&gt;onError&lt;/strong&gt;() method. Very nice.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2AaShPUKwwMK0NdElcNAczUw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2AaShPUKwwMK0NdElcNAczUw.gif" width="8" height="16"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F07k2fbiv0hwmzkecxaw0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F07k2fbiv0hwmzkecxaw0.png" width="800" height="700"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/word_pair_timer.dart#L139" rel="noopener noreferrer"&gt;word_pair_timer.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj2ag5pglu12prxyd5w03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj2ag5pglu12prxyd5w03.png" width="590" height="1250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe0o8ipw9gkpgsuvb9xgy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe0o8ipw9gkpgsuvb9xgy.png" width="800" height="693"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a&gt;page_01.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2AiHILCM-DhBLrnnvDYGfkdg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2AiHILCM-DhBLrnnvDYGfkdg.gif" width="8" height="16"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9r0tq6a8o7ockjnmjuol.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9r0tq6a8o7ockjnmjuol.png" width="800" height="824"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff920g265j1ovs8zvytj1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff920g265j1ovs8zvytj1.png" width="581" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxf52puvwqgrc53wsaacx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxf52puvwqgrc53wsaacx.png" width="800" height="698"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/word_pair_timer.dart#L123" rel="noopener noreferrer"&gt;word_pair_timer.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq6tb0ew1gua768kucdvz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq6tb0ew1gua768kucdvz.png" width="800" height="699"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part01_statex.dart#L955" rel="noopener noreferrer"&gt;pat01_statex.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdrncthdpk4pu401pi8gb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdrncthdpk4pu401pi8gb.png" width="800" height="698"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part01_statex.dart#L970" rel="noopener noreferrer"&gt;part01_statex.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  Testing Your App&lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;If I were you, a great way to get to know StateX would be to step through its accompanying &lt;a href="https://github.com/AndriousSolutions/state_extended/tree/master/example" rel="noopener noreferrer"&gt;test files&lt;/a&gt; that run whenever a new version of its package is pushed up to its GitHub &lt;a href="https://github.com/AndriousSolutions/state_extended" rel="noopener noreferrer"&gt;repository&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The screenshots below will give you an idea what will be covered in the nextt article.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2AUcZGDiQqdqX0UDwfY5QBRg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2AUcZGDiQqdqX0UDwfY5QBRg.gif" width="8" height="16"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo3oh20ch0190xd3ka3ky.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo3oh20ch0190xd3ka3ky.png" width="800" height="691"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/test/widget_test.dart#L99" rel="noopener noreferrer"&gt;test_widget.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flgfnkpx137aa8lcuq31g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flgfnkpx137aa8lcuq31g.png" width="800" height="692"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/integration_test/_integration_testing.dart#L16" rel="noopener noreferrer"&gt;intergration_testing.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  Unit Testing &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9db2lhl4124vvggmwsra.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9db2lhl4124vvggmwsra.png" width="800" height="700"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/test/test_app_state.dart#L16" rel="noopener noreferrer"&gt;test_app_state.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwp2a04jepbk8p6oqtr1w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwp2a04jepbk8p6oqtr1w.png" width="800" height="695"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/test/test_statex.dart#L17" rel="noopener noreferrer"&gt;test_statex.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwdogdc9hd26rnpbq9g8q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwdogdc9hd26rnpbq9g8q.png" width="800" height="685"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/test/test_statexcontroller.dart#L13" rel="noopener noreferrer"&gt;test_statexcontroller.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F47hpvvohw6yshv9jb13j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F47hpvvohw6yshv9jb13j.png" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/test/test_run_mixins.dart#L12" rel="noopener noreferrer"&gt;test_run_mixins.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffpkrg0n42zjxmq9r3818.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffpkrg0n42zjxmq9r3818.png" width="800" height="695"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/test/test_event_handling.dart#L97" rel="noopener noreferrer"&gt;test_event_handling.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi21qm493nbl6pgetafs8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi21qm493nbl6pgetafs8.png" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/test/test_event_handling.dart#L137" rel="noopener noreferrer"&gt;test_event_handling.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F086qnya57tgz1t3i22ug.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F086qnya57tgz1t3i22ug.png" width="800" height="691"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/test/test_event_handling.dart#L11" rel="noopener noreferrer"&gt;test_event_handling.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0pvavajtufou220oxne9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0pvavajtufou220oxne9.png" width="800" height="698"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/integration_test/reset_page1_count.dart#L11" rel="noopener noreferrer"&gt;reset_page1_count.dart&lt;/a&gt;



</description>
      <category>programming</category>
      <category>flutter</category>
    </item>
    <item>
      <title>You Can’t Have It All!</title>
      <dc:creator>Greg Perry</dc:creator>
      <pubDate>Thu, 10 Apr 2025 14:48:19 +0000</pubDate>
      <link>https://dev.to/andrious/you-cant-have-it-all-1o04</link>
      <guid>https://dev.to/andrious/you-cant-have-it-all-1o04</guid>
      <description>&lt;p&gt;&lt;em&gt;…or can you?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The last article, &lt;a href="https://dev.to/andrious/its-not-flutter-27co"&gt;It’s Not Flutter&lt;/a&gt;, brought a surge of downloads for my &lt;a href="https://pub.dev/packages/fluttery_framework" rel="noopener noreferrer"&gt;Fluttery Framework&lt;/a&gt; package. I received some great feedback, and have since then tightened up the code. It does what I always wanted Flutter itself to do:&lt;/p&gt;

&lt;p&gt;Run one codebase on more than one platform.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A9Mtbjw6-TRMbqKpkFcx2PQ.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A9Mtbjw6-TRMbqKpkFcx2PQ.jpeg" alt="[It’s Not Flutter](https://dev.to/andrious/its-not-flutter-27co)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After all, that was Flutter‘s mantra when it first came out, right? Flutter will run your app on your iPhone, on your Android, on the Web, on Windows, and on the Mac, etc — with only one codebase. However, I realized it doesn’t. Not with ease anyway. For me, it needed a few more ‘build’ functions:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;build&lt;/strong&gt;(); You already know this function. It comes with Flutter.&lt;br&gt;
&lt;strong&gt;buildAndroid&lt;/strong&gt;(); Returns a Widget for the Material interface.&lt;br&gt;
&lt;strong&gt;buildiOS&lt;/strong&gt;(); Returns a Widget for the Cupertino interface.&lt;br&gt;
&lt;strong&gt;builder&lt;/strong&gt;(); Runs the desired widget: &lt;em&gt;CupertinoApp&lt;/em&gt; or &lt;em&gt;MaterialApp&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;
  Table Of Contents
  &lt;br&gt;
Multiplatform&lt;br&gt;
· It Can Do It All&lt;br&gt;
· Choice By Design&lt;br&gt;
· Change Face&lt;br&gt;
Time to Initialize&lt;br&gt;
· Startup Time&lt;br&gt;
· Takes Time&lt;br&gt;
Event Handling&lt;br&gt;
· The Events That Take Place&lt;br&gt;
· In The Beginning&lt;br&gt;
· The Route Taken&lt;br&gt;
· Page 1 and 2&lt;br&gt;
· Pop Back&lt;br&gt;
· It’s All Flutter&lt;br&gt;
· To Dispose Of&lt;br&gt;
· Play Well With Others&lt;br&gt;
· Separate Lifecycles&lt;br&gt;
Real-World Example&lt;br&gt;
· Timing is Everything&lt;br&gt;
· Sequence of Events&lt;br&gt;
· It Is Eventful&lt;br&gt;
· The Tree Is Key&lt;br&gt;
· Dispose Disposable?&lt;br&gt;
Error Handling&lt;br&gt;
· The State of Error&lt;br&gt;
· Push for Exception&lt;br&gt;
· It Takes Two&lt;br&gt;
· Counter The Exception&lt;br&gt;
· My Bad&lt;br&gt;
· To The Top&lt;br&gt;
· Other Handlers&lt;br&gt;
· Stops And Starts&lt;br&gt;
· A Bad Build&lt;br&gt;
· Seeing Red Not&lt;br&gt;
· It’s A Little More&lt;br&gt;


&lt;/p&gt;

&lt;h3&gt;
  
  
  What’s in it for me? &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;What’s in it for me?, you ask. There are a lot ‘State Management’ solutions out there, but what about other capabilities allowing for rapid development and for a reliable deliverable? For a production-worthy, cross-platform app, you also want the following:&lt;/p&gt;

&lt;p&gt;Multiplatform, Time to Initialize, Event Handling, and Error Handling&lt;/p&gt;

&lt;h2&gt;
  
  
  Multiplatform
&lt;/h2&gt;

&lt;h3&gt;
  
  
  It Can Do It All &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;After installing Fluttery, go to the pub.dev directory on your machine and seek out its example folder for an extensive example app. Run this example app on any device you want. It can do it all.&lt;/p&gt;

&lt;h3&gt;
  
  
  Choice By Design &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In Fluttery, every State object offers two additional ‘build’ functions: &lt;strong&gt;buildAndroid&lt;/strong&gt;(); and &lt;strong&gt;buildiOS&lt;/strong&gt;(); The first is for the Material interface design, and the second is for the Cupertino interface design. For example, implement both these functions, and your mobile app will look good on an Android device and on an iPhone. Depending on the platform it’s running on, your app will start with either the &lt;strong&gt;CupertinoApp&lt;/strong&gt; widget, or it will start with the &lt;strong&gt;MaterialApp&lt;/strong&gt; widget.&lt;/p&gt;

&lt;p&gt;Frankly, it’ll start up any interface design you choose. You’re free to use a third-party design as well (eg. &lt;a href="https://pub.dev/packages/fluent_ui" rel="noopener noreferrer"&gt;&lt;em&gt;fluent_ui&lt;/em&gt;&lt;/a&gt;) using yet another ‘build’ function, &lt;strong&gt;buildApp&lt;/strong&gt;(). See below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3206%2F1%2A09y6YIqLgGWWlX2r591RJw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3206%2F1%2A09y6YIqLgGWWlX2r591RJw.png" alt="[app.dart](https://github.com/AndriousSolutions/fluttery_builder/blob/master/lib/app/view/app.dart#L40)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Change Face &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In the video below, the example app is switching between the Material interface and Cupertino interface with just a tap—this merely demonstrates how Fluttery will readily run on &lt;em&gt;any&lt;/em&gt; accepted platform. The Counter page displayed extends from the class, &lt;em&gt;StateX&lt;/em&gt;. It is that class displayed in the first screenshot below. You can see the extra &lt;strong&gt;build&lt;/strong&gt;() functions mentioned above. The example app even switches between &lt;em&gt;version 1&lt;/em&gt; and &lt;em&gt;version 2&lt;/em&gt; of the Material design.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg5am4yljpyjco6fryrcq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg5am4yljpyjco6fryrcq.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91w4kzkmddj5si8943e5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91w4kzkmddj5si8943e5.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3204%2F1%2A5dF5ccsDcadWN2D7OgqqHQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3204%2F1%2A5dF5ccsDcadWN2D7OgqqHQ.png" alt="[app_statex.dart](https://github.com/AndriousSolutions/fluttery_framework/blob/28e93ebe031dc2a344e4b0ab84132a8347279141/lib/view/app_statex.dart#L2046) and [app_statex.dart](https://github.com/AndriousSolutions/fluttery_framework/blob/28e93ebe031dc2a344e4b0ab84132a8347279141/lib/view/app_statex.dart#L553)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The second screenshot above is the &lt;strong&gt;builder&lt;/strong&gt;() function for the App’s main State object (AppStateX). It is this function that is called again and again when switching between interfaces. It runs either the CupertinoApp widget or the MaterialApp widget — but only if a &lt;em&gt;null&lt;/em&gt; comes from the function, &lt;strong&gt;buildApp&lt;/strong&gt;(). See how that works? Let Fluttery worry about all this for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Time to Initialize
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Startup Time &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;When I first began working in Flutter, I saw many developers ‘initializing’ their app’s particular functions and features before the function, &lt;strong&gt;runApp&lt;/strong&gt;(), is even called. These were operations that had to be completed or at least initialized before the app even displays its first screen.&lt;/p&gt;

&lt;p&gt;Fluttery gives the State class an additional function called, &lt;strong&gt;initAsync&lt;/strong&gt;(), to initialize such features. Think of it as an &lt;strong&gt;initState&lt;/strong&gt;() function for asynchronous operations. Any such operations will be completed before the State object proceeds (using a FutureBuilder). The video below demonstrates this. See the ‘spinner’ going around and around in the center of the screen at startup? That could be any intense operation (eg. opening databases, accessing web services, etc.). Any operation that must be completed before the app can present the demo app. If you like, instead of a spinner, you can display a fanciful startup screen to keep your users entertained while they wait. Let Fluttery worry about all this for you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwr7p538xrrd3dtpr59s8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwr7p538xrrd3dtpr59s8.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxbfk229vuwdde410dpjs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxbfk229vuwdde410dpjs.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3200%2F1%2AoZdaEz4vA6J-Bo-M-zVwaQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3200%2F1%2AoZdaEz4vA6J-Bo-M-zVwaQ.png" alt="[app_controller.dart](https://github.com/AndriousSolutions/fluttery_framework/blob/28e93ebe031dc2a344e4b0ab84132a8347279141/example/lib/src/app/controller/app_controller.dart#L212) and [image_api_conroller.dart](https://github.com/AndriousSolutions/fluttery_framework/blob/28e93ebe031dc2a344e4b0ab84132a8347279141/example/lib/src/main/grid_app_example/gridview/controller/image_api_controller.dart#L42)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Takes Time &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The first screenshot above reveals that this app is not opening a database at startup. It’s simply counting to 10 before proceeding — but you get the idea. However, further into the example app, a number of somewhat unreliable web services are being called (see the second screenshot above). Twelve &lt;strong&gt;initAsync&lt;/strong&gt;() functions are utilized to display a grid of animals. You can see twelve spinners appear before pictures of animals are displayed. Note, how some of them take their sweet time to complete. Fluttery has all that built-in.&lt;/p&gt;

&lt;p&gt;See how modular the code is? Such asynchronous code is located where it is required and executed when it is needed. That’s very nice. Fluttery even handles any errors that may occur in the &lt;strong&gt;initAsync&lt;/strong&gt;() function and provides a function for you to implement when such errors occur: &lt;br&gt;
&lt;em&gt;void onAsyncError(FlutterErrorDetails details) {&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What else do you want?&lt;/p&gt;

&lt;h2&gt;
  
  
  Event Handling
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Events That Take Place &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;You want to know what’s going on in your app. There’s so much going on in a typical Flutter app. Fluttery turns to Flutter itself to offer an array of event handlers that will address all that’s going on in your app.&lt;/p&gt;

&lt;p&gt;Look at the two screenshots below. They’re the result of &lt;a href="https://api.flutter.dev/flutter/foundation/debugPrint.html" rel="noopener noreferrer"&gt;&lt;strong&gt;debugPrint&lt;/strong&gt;()&lt;/a&gt; functions placed throughout the example app called in Flutter’s many Event Handlers. They print out on your IDE’s console the name of the handler, the Controller, and the State object involved. I’ve placed them throughout the example app for your benefit so you can see the extent of control you have while running your app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjhi42etf24butvzkacnk.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjhi42etf24butvzkacnk.gif" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fca0cjsq1crplvurzoi7t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fca0cjsq1crplvurzoi7t.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwh3nwtutf4je2rtoo3jh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwh3nwtutf4je2rtoo3jh.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Those two screenshots convey the events fired when simply tapping through the example app’s screens and back again (see video). Pretty intense, right? That’s always going on in your apps — you should be aware of them. The free article below details this further.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AwbCwEh0SKC7-Ui8YUmFkEg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AwbCwEh0SKC7-Ui8YUmFkEg.png" alt="[Little More Life Cycle Handling](https://andrious.medium.com/little-more-life-cycle-handling-d9111d58194d)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  In The Beginning &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The first screenshot below displays some of the handlers represented by the &lt;strong&gt;debugPrint&lt;/strong&gt;() function calls. Of course, there’s much more going on when starting up your app, but let’s see what’s conveyed here. The first State object, &lt;em&gt;_ExampleAppState&lt;/em&gt;, is starting up accompanied by it Controller object, &lt;em&gt;AppController&lt;/em&gt;. Note how the State object fires its Controller object’s event handlers before its own — very important.&lt;/p&gt;

&lt;p&gt;This order of events is an exception at startup as the remaining screens will call the &lt;strong&gt;initState&lt;/strong&gt;() function first then the &lt;strong&gt;initAsync&lt;/strong&gt;() function. It’s unique at startup because that’s when you would initialize the many functions and features you want to accompany your app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6j6mj7s227yi3p8oor3c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6j6mj7s227yi3p8oor3c.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3212%2F1%2AOf8ghwAye9EuK7xVg5K-XQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3212%2F1%2AOf8ghwAye9EuK7xVg5K-XQ.png" alt="[app.dart](https://github.com/AndriousSolutions/fluttery_framework/blob/28e93ebe031dc2a344e4b0ab84132a8347279141/example/lib/src/app/view/app.dart#L30)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Route Taken &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;See how Fluttery highlights when a Route is taken moving from one screen to another? The home screen, of course, is opened at startup, and that’s represented by the &lt;strong&gt;didPush&lt;/strong&gt;() function. Even before the State object’s &lt;strong&gt;initState&lt;/strong&gt;() function is called, its &lt;strong&gt;didPush&lt;/strong&gt;() function is called — very useful.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiozmzizr6goynap3fhbo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiozmzizr6goynap3fhbo.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The list of &lt;strong&gt;didChangeMetrics&lt;/strong&gt;() functions in the screenshot below tells you the interface is finalizing its components’ size and position. Things will soon settle down, and the app will then wait for user input — and it gets it right away. The current Controller and State object notes we’re pushing onto another screen with the function call, &lt;strong&gt;didPushNext&lt;/strong&gt;(). Think of this event as, “We’re now leaving ‘CounterController’ and _CounterPageState and pushing to the ‘next’ screen. Act accordingly.”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwlo46v8tyd0aua0nhbjq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwlo46v8tyd0aua0nhbjq.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I haven’t ‘reinvented the wheel’ here. This is all coming from Flutter. I simply consolidated these capabilities into my ‘framework package’ called, &lt;a href="https://pub.dev/packages/fluttery_framework" rel="noopener noreferrer"&gt;Fluttery&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Page 1 and 2 &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;We’re arriving on Page 1 in the next screenshot below. Even before its State object’s &lt;strong&gt;initState&lt;/strong&gt;() function is called, its Controller’s and then its own &lt;strong&gt;didPush&lt;/strong&gt;() function is called. Very nice. What follows, of course, are their &lt;strong&gt;initState&lt;/strong&gt;(), their &lt;strong&gt;didChangeDependencies&lt;/strong&gt;(), and their &lt;strong&gt;initAsync&lt;/strong&gt;() functions before Page 1 is displayed. After all that, we can tell we’re moving off Page 1 with the &lt;strong&gt;didPushNext&lt;/strong&gt;() function calls. See how this works? We go all the way to Page 3 in this exercise.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkhrrmr6d8cw1ptpv5rmp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkhrrmr6d8cw1ptpv5rmp.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Pop Back &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In the next few screenshots, let’s start heading back from Page 3 back to the home screen. With Fluttery, you can run code when such events happen. For example, you can restart features when returning to previous screens, or validate data retrieved when leaving a screen, etc. You can control the processes involved when switching between your app’s screens.&lt;/p&gt;

&lt;h3&gt;
  
  
  It’s All Flutter &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Please, take a look at the screenshot below. If you know Flutter, you’ll know what’s happening in the sequence of events displayed there. This involves Page 3 in the example app. Now, its State object doesn’t have an accompanying Controller object, but that’s perfectly fine. No law says you need to use them. You can see it ran its &lt;strong&gt;initAsync&lt;/strong&gt;() function (only to call &lt;strong&gt;debugPrint&lt;/strong&gt;() mind you), but then Page 2 calls its &lt;strong&gt;didPopNext&lt;/strong&gt;() function? Flutter’s telling you we’re coming back to Page 2 — act accordingly.&lt;/p&gt;

&lt;p&gt;What follows then is very interesting. The State object in Page 3 calls its &lt;strong&gt;didPop&lt;/strong&gt;(), its &lt;strong&gt;deactivate&lt;/strong&gt;(), and its &lt;strong&gt;dispose&lt;/strong&gt;() in that order. Page 3 is closing and being cleared from memory — and you have the handlers available to address when a State object is shutting down. That’s very very nice. Particularly with how &lt;em&gt;unreliable&lt;/em&gt; the &lt;strong&gt;dispose&lt;/strong&gt;() function can be. More on that next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff66zqs4xt6ntvyjne7ga.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff66zqs4xt6ntvyjne7ga.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  To Dispose Of &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The next screenshot has Page 2 closed and cleared from memory. We see its accompanying controller named ‘Controller’ is calling its event handlers as well. However, note the oddity in the Controller’s &lt;strong&gt;dispose&lt;/strong&gt;() function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftzvxjbclyg517xc59rdf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftzvxjbclyg517xc59rdf.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Page 1 and Page 2 share a controller named ‘Controller.’ It has retreated to its previous and first associated State object, &lt;em&gt;Page1State&lt;/em&gt;. That’s because we don’t want any reference to a State object that’s about to ‘go away’ from memory — if and when it calls its &lt;strong&gt;dispose&lt;/strong&gt;() function. ‘If and when?’, you say? More on that shortly.&lt;/p&gt;

&lt;p&gt;In the final screenshot below, Page 1 is now being cleared from memory. There should be no reference to its only State object by the time this &lt;strong&gt;dispose&lt;/strong&gt;() function is called. At this point, the controller should have no associated State object, and so it returns null below. Makes sense?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqzomq5o4wpg31bx2nuey.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqzomq5o4wpg31bx2nuey.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Play Well With Others &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Now, as much as you would like it to be the case, yours will not be the only app running on your user’s device. There are also event handlers for when your user moves off your app (placing it in the background) only to return from some other app at some point later. You should handle such situations as well.&lt;/p&gt;

&lt;p&gt;Let’s look at the video below. Tapping Android’s ‘Recents’ button will place the example app in the background. Another tap on the app itself returns it to the foreground. You will want to handle the events that occur during this time. You have the handlers to do it. Please, tap on the screenshots below for a closer look.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpeslvz7hhq0s43pufszr.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpeslvz7hhq0s43pufszr.gif" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj79x9iuejiya4glubb4x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj79x9iuejiya4glubb4x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmltp1pt50rofhua4rr5j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmltp1pt50rofhua4rr5j.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Separate Lifecycles &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;These are handlers you haven’t seen before. Note the order they are called. They’re fired ‘from the ground up’ up to the currently displayed screen running the State object, &lt;em&gt;_CounterPageState&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3fup3ls7ee8wwd6w3ab3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3fup3ls7ee8wwd6w3ab3.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Returning to the app, the last screen’s controller and State object are the last objects to fire their ‘resumed’ event handlers. See below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqonbd2qz133xy0mq1qk8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqonbd2qz133xy0mq1qk8.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Below, the event handlers are all listed together. You can see these ‘system’ event handlers behave a little differently than those you’ll encounter in Flutter itself. They are dependent on the particular platform the app is running on — some don’t exist depending on the platform. Notice your app returns to the foreground only after running the ‘hidden’ and ‘inactive’ functions once again. Finally, the function, &lt;strong&gt;resumedLifecycleState&lt;/strong&gt;() is called in the Controller and the &lt;strong&gt;didChangeAppLifecycleState&lt;/strong&gt;() function with the parameter value, &lt;strong&gt;AppLifecycleState.resumed&lt;/strong&gt;, is called in the State object. Fluttery is doing this all for you. Event handling is very important.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7zksbbx5weeskid8j8hn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7zksbbx5weeskid8j8hn.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc21s9h7yldzipq2iymnp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc21s9h7yldzipq2iymnp.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Example
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Timing is Everything &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Let’s give you a real-world example of its importance. When this example app starts, there’s a ‘word-pair’ displayed in red and placed in the center of the screen. To produce these pairs, a Timer is calling the package, &lt;a href="https://pub.dev/packages/english_words" rel="noopener noreferrer"&gt;&lt;strong&gt;english_words&lt;/strong&gt;&lt;/a&gt;, at a steady interval. It’s always running in the background. Granted, it’s not taking up too much resources, but imagine a more substantial process always running in the background — one running in your own app. You should have some control over these background processes.&lt;/p&gt;

&lt;p&gt;In the video below, when we tap off the first screen to Page 1 screen, the Timer is stopped. It would be a waste running this process in the background when it is no longer needed. The first screenshot shows the event handlers involved. Note, the second screenshot handles a different scenario altogether. The second scenario shows the Timer initialized at startup and turned off when the app closes using the ‘deactivate’ event. By the way, when is the ‘activate’ event triggered? I’ll tell you soon. Hint: Widget tree.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fojto9p5tceca1j7rpcrm.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fojto9p5tceca1j7rpcrm.gif" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fue4mw97wixp9pupxira5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fue4mw97wixp9pupxira5.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3200%2F1%2ABRjk9CLQLklyuV1Ex2VlbQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3200%2F1%2ABRjk9CLQLklyuV1Ex2VlbQ.png" alt="[english_words_timer.dart](https://github.com/AndriousSolutions/fluttery_framework/blob/28e93ebe031dc2a344e4b0ab84132a8347279141/example/lib/src/app/controller/english_words_timer.dart#L114) and [english_words_timer.dart](https://github.com/AndriousSolutions/fluttery_framework/blob/28e93ebe031dc2a344e4b0ab84132a8347279141/example/lib/src/app/controller/english_words_timer.dart#L55)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the first screenshot above, the &lt;strong&gt;didPushNext&lt;/strong&gt;() method is triggered when the ‘Page 1’ button is pressed. Again, this is all about routes. You’re about to leave this first screen being ‘pushed to the next screen.’ Hence, the Timer is stopped with the function call, &lt;strong&gt;_cancelTimer&lt;/strong&gt;(). Note in the video we return from Page 1 almost immediately (i.e. The ‘next screen’ is popped almost immediately). That means the &lt;strong&gt;didPopNext&lt;/strong&gt;() function back in the first screen is fired and initializes the Timer again with &lt;strong&gt;_initTimer&lt;/strong&gt;(). See how that works?&lt;/p&gt;

&lt;h3&gt;
  
  
  Sequence of Events &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Revisiting Android’s ‘Recents’ button, when placing this example app in the background, a whole different sequence of events occurs below. In the first screenshot, you see the three event handlers involved. They're listed in the order they are fired in the controller, &lt;em&gt;EnglishWords&lt;/em&gt; Timer. In the second screenshot of that very same controller, you see the event handler, &lt;strong&gt;resumedAppLifecycleState&lt;/strong&gt;(). Again, it’s called when the example app is returned to the foreground. See how that all works? It’s how Flutter works. Fluttery just gives you the functions to work with it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpeslvz7hhq0s43pufszr.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpeslvz7hhq0s43pufszr.gif" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fot8vpgnflfan65mciexa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fot8vpgnflfan65mciexa.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3204%2F1%2ASDGzRwaoAsEobaVgKZeQTg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3204%2F1%2ASDGzRwaoAsEobaVgKZeQTg.png" alt="[english_words_timer.dart ](https://github.com/AndriousSolutions/fluttery_framework/blob/28e93ebe031dc2a344e4b0ab84132a8347279141/example/lib/src/app/controller/english_words_timer.dart#L88)and [english_words_timer.dart](https://github.com/AndriousSolutions/fluttery_framework/blob/28e93ebe031dc2a344e4b0ab84132a8347279141/example/lib/src/app/controller/english_words_timer.dart#L114)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  It Is Eventful &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Back in that video, the &lt;strong&gt;_cancelTimer&lt;/strong&gt;() function is called a total of five times. That’s because, as you’ve seen in the graphic below, Flutter will go back through those event handlers when bringing the app back into focus. That’s just the way it is. I involved all three methods here to demonstrate this. In truth, I would have only placed the &lt;strong&gt;_cancelTimer&lt;/strong&gt;()method in the &lt;strong&gt;inactiveAppLifecycleState&lt;/strong&gt;() method — for a total of two calls. The method, &lt;strong&gt;resumedAppLifecycleState&lt;/strong&gt;(), is then called going back so to initialize the Timer again. Perfect.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc21s9h7yldzipq2iymnp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc21s9h7yldzipq2iymnp.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3200%2F1%2ABRjk9CLQLklyuV1Ex2VlbQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3200%2F1%2ABRjk9CLQLklyuV1Ex2VlbQ.png" alt="[english_words_timer.dart](https://github.com/AndriousSolutions/fluttery_framework/blob/28e93ebe031dc2a344e4b0ab84132a8347279141/example/lib/src/app/controller/english_words_timer.dart#L55)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Tree Is Key &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Now, back to the ‘activate’ event. Know that a State object’s &lt;strong&gt;deactivate&lt;/strong&gt;() event handler is triggered in two instances: when their widget is closing and when their widget is moved around the Widget tree. The Widget tree makes Flutter fast. Widgets are moved around the tree to improve performance. When a widget is ‘reinserted’ into the Widget tree, its State object’s &lt;strong&gt;activate&lt;/strong&gt;() event handler is called — restarting the Timer in our case. See how that works?&lt;/p&gt;

&lt;h3&gt;
  
  
  Dispose Disposable? &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This is all because I don’t trust the &lt;strong&gt;dispose&lt;/strong&gt;() function. I need to call the _cancelTimer()routine and stop the Timer. However, I usually don’t use the &lt;strong&gt;dispose&lt;/strong&gt;() method to do this. It’s unreliable to run any mission-critical operations and or release any substantial resources. You see, it’s to the &lt;a href="https://github.com/flutter/engine" rel="noopener noreferrer"&gt;Virtual Machine&lt;/a&gt;’s (VM) (i.e. Flutter Engine) discretion to call a State object’s &lt;strong&gt;dispose&lt;/strong&gt;() function as part of its garbage collection responsibilities. &lt;em&gt;You will have no idea&lt;/em&gt; when that happens. Due to some memory constraints, it’s not called at all — at least not when you may want to. The &lt;strong&gt;deactivate&lt;/strong&gt;() method is more reliable and is more consistent. I use the &lt;strong&gt;deactivate&lt;/strong&gt;() method, but that means I also use the &lt;strong&gt;activate&lt;/strong&gt;() method — in case the Widget is moved around the Widget tree — the Timer must be initialized in our case. That’s just the way it is.&lt;/p&gt;

&lt;p&gt;What else do you want?&lt;/p&gt;

&lt;h2&gt;
  
  
  Error Handling &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Error handling is paramount. Your app is going to fail for any number of reasons, and you must have the code to address it. Your app must fail gracefully and close vulnerable resources before crashing. Your error handling should report and or log the problem with pertinent information. If the situation permits, maybe your app can even recover and continue on. Granted, recovery is the exception, but Fluttery offers the possibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  The State of Error &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Every State object has the &lt;strong&gt;onError&lt;/strong&gt;() function. An error thrown in a Fluttery app will involve a State object if the code that errored was working ‘in’ that State object. The State object’s &lt;strong&gt;onError&lt;/strong&gt;() function is called:&lt;br&gt;
void onError(FlutterErrorDetails detials) {&lt;/p&gt;

&lt;h3&gt;
  
  
  Push for Exception &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In the video below, the example app throws an Exception with every tap on the ‘Counter’ button (+), but you’d never know it. The Exception is still reported and logged by its Error Handler, but the State object’s &lt;strong&gt;onError&lt;/strong&gt;() function recognizes this particular Exception, and attempts to increment the counter regardless.&lt;/p&gt;

&lt;p&gt;A very very simple scenario, where the Exception is anticipated (i.e. it’s explicitly thrown). However, Fluttery allows you to take into account such scenarios. You may have situations in your app where the typical process will encounter anticipated exceptions —and possibly you’re then able to overcome them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy22fnbhbk0av5bmppzxk.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy22fnbhbk0av5bmppzxk.gif" alt=" "&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4s9o3e3bd88qa1twg0vk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4s9o3e3bd88qa1twg0vk.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/fluttery_framework/blob/28e93ebe031dc2a344e4b0ab84132a8347279141/example/lib/src/main/view/screens/app_counter.dart#L127" rel="noopener noreferrer"&gt;app_counter.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqhogtvgz2i98cz02hzg1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqhogtvgz2i98cz02hzg1.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/fluttery_framework/blob/28e93ebe031dc2a344e4b0ab84132a8347279141/example/lib/src/main/view/screens/app_counter.dart#L252" rel="noopener noreferrer"&gt;app_counter.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  It Takes Two &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In Flutter, there are two types of ‘errors.’ In Flutter itself, with certain bits of code, an exception is anticipated to occur from time to time. Such code is likely called within a &lt;strong&gt;try&lt;/strong&gt;-&lt;strong&gt;catch&lt;/strong&gt; statement to indeed catch such exceptions. In the &lt;strong&gt;catch&lt;/strong&gt; clause, an &lt;em&gt;Exception&lt;/em&gt; object is instantiated and ‘handled’ accordingly.&lt;/p&gt;

&lt;p&gt;The other type of error is considered ‘an error on the part of the developer.’ However, even an unanticipated issue must be addressed. For such failures, it’s preferred the &lt;em&gt;Error&lt;/em&gt; class and its subclasses be used.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.google.com/search?q=%22An+Error+object+represents+a+program+failure+that+the+programmer+should+have+avoided%22" rel="noopener noreferrer"&gt;&lt;em&gt;An Error object represents a program failure that the programmer should have avoided&lt;/em&gt;&lt;/a&gt;. — Google Search.&lt;/p&gt;

&lt;h3&gt;
  
  
  Counter The Exception &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In the first screenshot above, when switched on, the State object, &lt;em&gt;_CounterPageState&lt;/em&gt;, explicitly throws, Exception('Fake error to demonstrate error handling'). The next screenshot is of that State object’s &lt;strong&gt;onError&lt;/strong&gt;() routine. It is seeking out that specific problem and addressing it accordingly.&lt;/p&gt;

&lt;h3&gt;
  
  
  My Bad &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Now, ‘handle your errors’ does not mean ‘ignore them completely.’ That’s a no, no. I’m sure you could find a way, but I wouldn’t ignore any errors or exceptions. Even with the ‘Counter’ button problem seemingly ‘handled,’ the example app’s error handler doesn’t neglect to record and report the problem as well. See the console screenshot below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyyljtra31vms4vdv8eo6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyyljtra31vms4vdv8eo6.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  To The Top &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Again, every State object has an &lt;strong&gt;onError&lt;/strong&gt;() function. An exception will be sent to the State object that the troublesome code was likely working with. Regardless, the App’s first State object’s &lt;strong&gt;onError&lt;/strong&gt;() routine is always called. Being the ‘head honcho’ of State objects in your app, the AppStateX object is notified of all exceptions or errors that may occur in your app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy22fnbhbk0av5bmppzxk.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy22fnbhbk0av5bmppzxk.gif" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqhogtvgz2i98cz02hzg1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqhogtvgz2i98cz02hzg1.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3192%2F1%2AT9RBrj5y-IKszfs4wMvL0g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3192%2F1%2AT9RBrj5y-IKszfs4wMvL0g.png" alt="[app_counter.dart](https://github.com/AndriousSolutions/fluttery_framework/blob/28e93ebe031dc2a344e4b0ab84132a8347279141/example/lib/src/main/view/screens/app_counter.dart#L252) and [app.dart](https://github.com/AndriousSolutions/fluttery_framework/blob/28e93ebe031dc2a344e4b0ab84132a8347279141/example/lib/src/app/view/app.dart#L244)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Above is the screenshot of State object, &lt;em&gt;_CounterPageState&lt;/em&gt;, again. It fires its &lt;strong&gt;onError&lt;/strong&gt;() routine with every tap of the button. The second screenshot is of the AppStateX object, &lt;em&gt;_ExampleAppState&lt;/em&gt;, displaying its &lt;strong&gt;onError&lt;/strong&gt;() routine. It takes in that particular exception as well. Broadcasting errors to the ‘governing part’ of an app is just good practice. For example, when working with a team of developers, one programmer can’t just hide their errors while developing some remote screen somewhere—all errors are sent to the App’s ‘main’ State object as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  Other Handlers  &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;With Fluttery, you’re free to utilize other third-party error handlers like &lt;a href="https://firebase.google.com/docs/crashlytics" rel="noopener noreferrer"&gt;Firebase Crashlytics&lt;/a&gt;, &lt;a href="https://pub.dev/packages/catcher_2" rel="noopener noreferrer"&gt;Catcher 2&lt;/a&gt;, etc. These products will notify you directly about a problem right then and there. You can then be more proactive when addressing such issues.&lt;/p&gt;

&lt;p&gt;Below is a screenshot of what an App’s &lt;strong&gt;initAsync&lt;/strong&gt;() function could contain, for example, when setting up &lt;a href="https://firebase.google.com/docs/crashlytics" rel="noopener noreferrer"&gt;Firebase Crashlytics&lt;/a&gt; as its Error Handler and reporting system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F1%2ALISuSrp1I2YaFnkvsf8EEA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F1%2ALISuSrp1I2YaFnkvsf8EEA.png" alt="[working_memory_app.dart](https://github.com/Andrious/workingmemory/blob/a8262ff0ea3389bdbbc52ced0c5b903b8cf68788/lib/src/app/controller/working_memory_app.dart#L147)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Stops And Starts  &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Fluttery provides an important capability to your apps. Again, it allows your app to perform extensive and complicated operations asynchronously using the function, &lt;strong&gt;initAsync&lt;/strong&gt;(). Every State object in Fluttery has one so as to localize such operations to run when and where they’re required.&lt;/p&gt;

&lt;p&gt;These operations are likely critical and must be completed successfully for your app to proceed. The need for error handling during such operations will be of great importance. A handler to log, report, and possibly even recover from errors in the function, &lt;strong&gt;initAsync&lt;/strong&gt;(), may prove very helpful to you.&lt;/p&gt;

&lt;p&gt;In the video below, an &lt;strong&gt;initAsync&lt;/strong&gt;() function explicitly throws an Exception (if permitted) when the ‘Page 1’ button is tapped. The first screenshot has the Exception thrown, while the second screenshot introduces you to the &lt;strong&gt;onCatchAsyncError&lt;/strong&gt;() function. Note, that specific Exceptions are anticipated in this function and will return &lt;em&gt;true&lt;/em&gt; when encountered. Consequently, the ‘Page 1’ screen appears seemingly without incident.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv6lqtswevuup3r39t3u2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv6lqtswevuup3r39t3u2.gif" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3u0cgz78uarml09o053p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3u0cgz78uarml09o053p.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3000%2F1%2AQzEyTd4L3nBJsZllUjqPqA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3000%2F1%2AQzEyTd4L3nBJsZllUjqPqA.png" alt="[controller.dart](https://github.com/AndriousSolutions/fluttery_framework/blob/28e93ebe031dc2a344e4b0ab84132a8347279141/example/lib/src/main/view/screens/counter/controller/controller.dart#L55) and [app.dart](https://github.com/AndriousSolutions/fluttery_framework/blob/28e93ebe031dc2a344e4b0ab84132a8347279141/example/lib/src/app/view/app.dart#L226)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, they are still Exceptions, and so error handlers log it accordingly. Note below, a console lists the &lt;strong&gt;debugPrint&lt;/strong&gt;() function outputs indicating the many handlers involved.&lt;/p&gt;

&lt;p&gt;The exception occurred in ‘Page 1’ and so its &lt;strong&gt;onError&lt;/strong&gt;() is called. The app’s main State object, &lt;em&gt;_ExampleAppState&lt;/em&gt;, will then call its &lt;strong&gt;onError&lt;/strong&gt;() function. Being an ‘Asynchronous’ error, its &lt;strong&gt;onCatchAsyncError&lt;/strong&gt;() function is then called. That’s the second screenshot above, and because it returns, &lt;em&gt;true&lt;/em&gt;, the ‘Page 1’ screen appears.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdjxogxwc2y6aoor4oxi2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdjxogxwc2y6aoor4oxi2.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, below is what happens if it returns false (see the second screenshot below). The screen, Page 1, fails outright and the good old ‘Red Screen of Doom’ is instead displayed. If running in Production, it turns out to be an ugly, ‘Grey Screen of Doom.’&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffn7ezgbcrf45r7ai83r4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffn7ezgbcrf45r7ai83r4.gif" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7c0zlo4meor5iv7cfzs3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7c0zlo4meor5iv7cfzs3.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3000%2F1%2AxpGszAkSzJE2c6aaV2nVig.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3000%2F1%2AxpGszAkSzJE2c6aaV2nVig.png" alt="[controller.dart](https://github.com/AndriousSolutions/fluttery_framework/blob/28e93ebe031dc2a344e4b0ab84132a8347279141/example/lib/src/main/view/screens/counter/controller/controller.dart#L55) and [app.dart](https://github.com/AndriousSolutions/fluttery_framework/blob/28e93ebe031dc2a344e4b0ab84132a8347279141/example/lib/src/app/view/app.dart#L226)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, what’s stopping you from always returning true when errors occur in an &lt;strong&gt;initAsync&lt;/strong&gt;() function? Remember, these operations are likely critical and must be completed successfully. Frankly, if you ignore such errors, that’s on you. They’re still reported to the ‘main’ State object in your app.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Bad Build &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In the video below, another exception occurs in a ‘build’ function obligated to return a Widget. It occurs when moving to Page 2. The first screenshot below displays the &lt;strong&gt;throw&lt;/strong&gt; statement involved.&lt;/p&gt;

&lt;p&gt;In the second screenshot below, you can see in Flutter itself, the &lt;strong&gt;build&lt;/strong&gt;() function is called in a &lt;strong&gt;try-catch&lt;/strong&gt; statement. When an error occurs right in a &lt;strong&gt;build&lt;/strong&gt;() function, something has to be displayed, and so the ErrorWidget.&lt;strong&gt;builder&lt;/strong&gt;() produces the good old ‘Red Screen of Doom.’&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyfzpuh03keds4hjhwrt8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyfzpuh03keds4hjhwrt8.gif" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdmepz5cyp1ildhb9c6ly.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdmepz5cyp1ildhb9c6ly.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3206%2F1%2A5GoxbZ7q2gZ_G8DkLtTELg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3206%2F1%2A5GoxbZ7q2gZ_G8DkLtTELg.png" alt="[page_02.dart](https://github.com/AndriousSolutions/fluttery_framework/blob/28e93ebe031dc2a344e4b0ab84132a8347279141/example/lib/src/main/view/screens/counter/view/page_02.dart#L84) and [framework.dart](https://github.com/flutter/flutter/blob/7d56be4c8de814022357633179a816b51ffca4b8/packages/flutter/lib/src/widgets/framework.dart#L5708)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Seeing Red Not &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;As you see in the first screenshot below, from the very beginning, the App’s State object, &lt;em&gt;_ExampleAppState&lt;/em&gt;, has been using Fluttery’s standard Error Handler: AppErrorHandler.errorHandler&lt;br&gt;
Of course, you’re free to assign your own Error Handler.&lt;/p&gt;

&lt;p&gt;You’re also free to assign your own ‘Error Widget Builder’ to display a screen when a &lt;strong&gt;build&lt;/strong&gt;() function fails. In the first screenshot below, Fluttery offers a more helpful and more aesthetically pleasing screen using the parameter value, AppErrorHandler.displayErrorWidget.The videos below have the same two errors that were tripped above. This time, however, you’re not seeing red.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0fxpmp8tq4696mryjze.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0fxpmp8tq4696mryjze.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx4tgcp2w369pkushjibn.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx4tgcp2w369pkushjibn.gif" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcs31kqnuq5whrgdr576l.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcs31kqnuq5whrgdr576l.gif" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  It’s A Little More &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;There you have it. The Fluttery State class has a little more functionality (i.e. a few more functions) to supply ‘a little more’ of what I feel is required for a production-worthy, cross-platform app:&lt;/p&gt;

&lt;p&gt;Multiplatform, Time to Initialize, Event Handling, and Error Handling&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1rcwt1opwygyi97pmaet.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1rcwt1opwygyi97pmaet.png" alt="Functions in StateX"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Further information is in &lt;a href="https://andrious.medium.com/the-little-more-series-94b0a9c6cd25" rel="noopener noreferrer"&gt;the ‘Little More’ series&lt;/a&gt; of free articles (see below). I feel you’re going to want this. It’s all comes from Flutter. Just consolidated into one package: &lt;a href="https://pub.dev/packages/fluttery_framework" rel="noopener noreferrer"&gt;Fluttery Framework&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AZ1mI65H_X_RWvNH93hydGg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AZ1mI65H_X_RWvNH93hydGg.gif" alt="T[he ‘Little More’ Series](https://andrious.medium.com/the-little-more-series-94b0a9c6cd25)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cheers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpltx5rbibieriffn90sh.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpltx5rbibieriffn90sh.jpeg" alt="How about a clap? Just one, please."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://andrious.medium.com/" rel="noopener noreferrer"&gt;→ Other Articles by Greg Perry&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>programming</category>
    </item>
    <item>
      <title>The Fluttery Framework</title>
      <dc:creator>Greg Perry</dc:creator>
      <pubDate>Wed, 29 Jan 2025 16:26:52 +0000</pubDate>
      <link>https://dev.to/andrious/the-fluttery-framework-3kbn</link>
      <guid>https://dev.to/andrious/the-fluttery-framework-3kbn</guid>
      <description>&lt;p&gt;&lt;em&gt;A Framework that works with Flutter and works like Flutter&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Mike Rydstrom is known to post on his Twitter account a list of the Top 30 State Management library packages used by Flutter developers. Below, I believe, is the latest dated August 14, 2022. Tap on it to get a closer look.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F7680%2F1%2ACRS9vUW-IkQ1d8sz795AEg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F7680%2F1%2ACRS9vUW-IkQ1d8sz795AEg.jpeg" alt="[Top 30 Flutter State Management](https://twitter.com/RydMike/status/1558842084567797761/photo/1)" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google didn’t release Flutter ‘hard coded’ to one particular architecture. They left it to the IT industry to come up with different ways to work with Flutter. Hence the list above. After all, programming languages are called upon to work in almost every Use Case on Earth! Computer software can be found running in everything from a toaster to a nuclear submarine. By that very fact, it has to be intrinsically adaptive so as to meet very diverse and very complicated problem domains. Google knew you simply can’t supply a ‘one-size-fits-all’ approach when developing software. And so, I suspect that list will only grow longer.&lt;/p&gt;

&lt;p&gt;Of course, your users and particularly your boss will insist you only use the ‘best one’ listed above — which, as I’ve just hinted, is an impractical demand. However, time is money and in many cases, I suspect you’ll choose one simply because it follows a design pattern or style you’re familiar with. Still, other developers will look at that list, visit forums, ask around, and then simply pick what seems to be the most popular. Easy peasy.&lt;/p&gt;

&lt;p&gt;However, it’s not so easy. I’ve looked at that list — for most, you have to learn how to use your chosen approach. Today, I’ll introduce you to yet another library package. One I feel stands out from the rest. ‘Keep it Flutter’ has been my motto when building this framework. Most of those other library packages don’t work like Flutter itself. They sit on top of Flutter and have their own way of doing things. There‘s a learning curve not only to learn how Flutter works but how your chosen library package works as well.&lt;/p&gt;

&lt;p&gt;Below is a ‘paywalled’ article about the Provider package. The article is written by &lt;a href="https://medium.com/@suragch" rel="noopener noreferrer"&gt;Suragch&lt;/a&gt; — one of my favorite writers. I’ve always liked the title, &lt;em&gt;Making sense of all those Flutter Providers&lt;/em&gt;. The &lt;a href="https://pub.dev/packages/provider" rel="noopener noreferrer"&gt;Provider&lt;/a&gt; state management package was written by &lt;a href="https://www.linkedin.com/in/r%C3%A9mi-rousselet/?originalSubdomain=fr" rel="noopener noreferrer"&gt;Remi Rousselet&lt;/a&gt;, and to me, looks a lot like the &lt;a href="https://en.wikipedia.org/wiki/Provider_model" rel="noopener noreferrer"&gt;Provider Model&lt;/a&gt; introduced by Microsoft in 2002 — I suspect many of today’s Provider users were ASP.Net developers.&lt;/p&gt;

&lt;p&gt;Remi did some great work, but I chose not to use Provider. After all, Flutter has its own means of State Management. I wrote a framework to more effectively and more efficiently work with Flutter — like Flutter.&lt;br&gt;
&lt;a href="https://medium.com/flutter-community/making-sense-all-of-those-flutter-providers-e842e18f45dd" rel="noopener noreferrer"&gt;&lt;strong&gt;Making sense all of those Flutter Providers&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’re new to Flutter and want to learn Flutter, learn how to use this library package. Unlike those others, it’s a framework that works with Flutter, works like Flutter, and looks like Flutter. If you have a few years of experience in Flutter, you’ll recognize how this framework works. In this series of articles, you’ll be introduced to the Fluttery Framework through the demonstration of a number of example apps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkfbx01ssb5kdimdqd84w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkfbx01ssb5kdimdqd84w.png" width="800" height="216"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://pub.dev/packages/fluttery_framework" rel="noopener noreferrer"&gt;Fluttery Framework on Pub.dev&lt;/a&gt;



&lt;p&gt;Let’s begin.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc6jzvvnsx3o0kgfr99gj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc6jzvvnsx3o0kgfr99gj.gif" width="324" height="416"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://andrious.medium.com/my-medium-9de112c2d85c" rel="noopener noreferrer"&gt;More Stories by Greg Perry&lt;/a&gt;



&lt;h2&gt;
  
  
  Works with Flutter, Works Like Flutter
&lt;/h2&gt;

&lt;p&gt;This framework implements a SOC (State Object Controller) to accompany every State object used in your Flutter app. It does this by introducing the class, &lt;em&gt;StateX&lt;/em&gt;, which ‘extends’ Flutter’s State class to now include a controller. It is this controller object that performs the event handling and business rules specific to your app — much like the many Controller objects already found in Flutter. Again, I’m ‘keeping it Flutter.’&lt;/p&gt;

&lt;p&gt;Indeed, there are a number of widgets in Flutter with a named parameter called, controller. The widgets, &lt;strong&gt;TextField&lt;/strong&gt; and &lt;strong&gt;SingleChildScrollView&lt;/strong&gt; are two quick examples. They take in a controller object that provides an initial value or an initial position respectively as well as handle the common events and circumstances involved in their typical operation. It was back in 2018 when I first began working in Flutter that I quickly found it very productive and advantageous to introduce such a controller to Flutter’s own State class.&lt;/p&gt;

&lt;p&gt;Below are two screenshots of those two widgets I mentioned above — each with its own controller parameter highlighted with a little red arrow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1nwq1ixscvdh0cxaneva.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1nwq1ixscvdh0cxaneva.png" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/flutter/flutter/blob/4c8fa187f31dc5fb65c895533be429f2e0176a39/packages/flutter/lib/src/material/date_picker.dart#L2880" rel="noopener noreferrer"&gt;date_picker.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4156%2F1%2ANQ7tV8S_q5fK_g5oxvtxWw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4156%2F1%2ANQ7tV8S_q5fK_g5oxvtxWw.png" alt="[dialog.dart](https://github.com/flutter/flutter/blob/4c8fa187f31dc5fb65c895533be429f2e0176a39/packages/flutter/lib/src/cupertino/dialog.dart#L1479)" width="800" height="214"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  By Example
&lt;/h2&gt;

&lt;p&gt;Now, what better way to illustrate the implementation of the StateX class and the Fluttery Framework than demonstrating it in an example app? The &lt;a href="https://github.com/Andrious/fluttery_stocks" rel="noopener noreferrer"&gt;Stocks example app&lt;/a&gt; implements the Fluttery Framework. This little app supplies the option, ‘dev tools’, in its Drawer widget demonstrating the many development tools available to you when working in Flutter. In truth, it’s the Fluttery Framework that makes these tools readily available to you, and I’ll show you how in later articles but for now, let’s look at this StateX class and its controller.&lt;/p&gt;

&lt;h2&gt;
  
  
  The State Extended
&lt;/h2&gt;

&lt;p&gt;In the first screenshot below, you’re introduced to the StateX class for the first time. The little red arrows highlight this class and how its accompanying controller, &lt;em&gt;DevTools&lt;/em&gt;, is instantiated. It’s the StatefulWidget, &lt;em&gt;StockSettings&lt;/em&gt;, that presents the list of switches you see turning on and off an assortment of development tools. (Note, these tools can only be accessed while developing in your IDE or when you compile your Flutter app in debug mode.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2Ans6Y1H_SM4qpVDFMQ2jjnQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2Ans6Y1H_SM4qpVDFMQ2jjnQ.gif" alt="gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0l5ex5xyyhwycqdyybgg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0l5ex5xyyhwycqdyybgg.png" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4000%2F1%2AymJOWmJ_w3VJrgK6g3yGBA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4000%2F1%2AymJOWmJ_w3VJrgK6g3yGBA.png" alt="[dev_settings.dart](https://github.com/Andrious/fluttery_stocks/blob/2f274955807d7ec7009c8170b7a41e5aaf8c22f9/lib/src/app/view/dev_settings.dart#L6) and [dev_setings.dart](https://github.com/Andrious/fluttery_stocks/blob/2f274955807d7ec7009c8170b7a41e5aaf8c22f9/lib/src/app/view/dev_settings.dart#L56)" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The second screenshot above is a portion of that State object’s &lt;strong&gt;build&lt;/strong&gt;() function displaying two of those switches. Note the distinct separation of work: the State object’s &lt;strong&gt;build&lt;/strong&gt;() function is concerned with ‘how’ things are displayed in the interface (i.e. with its Switch widgets) while its controller instantiated to the property variable, &lt;em&gt;con&lt;/em&gt;, is more concerned with what’s actually being displayed as well as any event handling —this separation of responsibility is a core concept in clean architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Controller Pattern
&lt;/h2&gt;

&lt;p&gt;By the way, that’s the consistent pattern you’ll see in the Fluttery Framework example apps:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A controller is passed to the StateX object’s parent class constructor, it’s then assigned to a property variable (usually named ‘con’) either in the StateX class’ constructor or in its &lt;strong&gt;initState&lt;/strong&gt;() function. That ‘con’ variable is then referenced here and there in the &lt;strong&gt;build&lt;/strong&gt;() function and in any other function defined in that class and will primarily be involved in the app’s overall business logic and event handling.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The first screenshot is again displayed below for your review. Further below, you’ll find those development tools displayed individually. Most are concerned with the fine-tuning of your app’s interface. In time, you’ll find them very useful in certain circumstances.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0l5ex5xyyhwycqdyybgg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0l5ex5xyyhwycqdyybgg.png" alt="[dev_settings.dart](https://github.com/Andrious/fluttery_stocks/blob/2f274955807d7ec7009c8170b7a41e5aaf8c22f9/lib/src/app/view/dev_settings.dart#L6)" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp2g0jdezbepnaq2v7eu8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp2g0jdezbepnaq2v7eu8.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AlQFnGJoSa2gIiyW0D-oElA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AlQFnGJoSa2gIiyW0D-oElA.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AfvvK5DQPZxwbunxn4eQzKg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AfvvK5DQPZxwbunxn4eQzKg.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2ApqLb3l6am6KHXt99WoJOhg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2ApqLb3l6am6KHXt99WoJOhg.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AUeTA5qB4BHzoS0Y1dXEoRg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AUeTA5qB4BHzoS0Y1dXEoRg.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AXPZS4MKIEgDkLaUWaxFnvQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AXPZS4MKIEgDkLaUWaxFnvQ.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AvBEI_kJpQqnpPnjRDWJBNA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AvBEI_kJpQqnpPnjRDWJBNA.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A7kWADKQsm-cCnoqtXgNgQQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A7kWADKQsm-cCnoqtXgNgQQ.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A0Q0t220MuhGUJoDBGLph6w.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A0Q0t220MuhGUJoDBGLph6w.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Set The State
&lt;/h2&gt;

&lt;p&gt;Now, all that flash and color you see displayed above just doesn’t magically appear when using Flutter. As a quick aside, we know HTML is a declarative programming language. When there’s a change made to a webpage, in most cases, that whole webpage is rendered all over again to then display that change. Well, Flutter apps create their interfaces in a pseudo-declarative fashion as well. This declarative characteristic of ‘rebuilding the interface all over again from scratch’ comes with every new call to a State object’s &lt;strong&gt;build&lt;/strong&gt;() function —the returning widget is often the result of a bunch of other widgets being built all over again. However, that call has to be made in the first place using the State object’s &lt;strong&gt;setState&lt;/strong&gt;() function.&lt;/p&gt;

&lt;p&gt;You can readily see above those Switch widgets being turned on and off. However, that’s only because the StatefulWidget, &lt;em&gt;StockSettings&lt;/em&gt;, is being rebuilt all over again. More accurately, its State object, &lt;em&gt;_StockSettingsState&lt;/em&gt;, is having its &lt;strong&gt;build&lt;/strong&gt;() function called again and that function’s content is being rebuilt all over again. In that screen full of Switch widgets, that State object’s &lt;strong&gt;setState&lt;/strong&gt;() function is being called somewhere. But where?&lt;/p&gt;

&lt;p&gt;Below, you see the ‘Performance overlay’ switch being turned on and off repeatedly. The first screenshot below highlights the Switch widget’s &lt;strong&gt;onChange&lt;/strong&gt;() function. With every tap of the widget, that &lt;strong&gt;onChange&lt;/strong&gt;() function is called, and as you can see, its controller is in charge of handling that event. So where is the &lt;strong&gt;setState&lt;/strong&gt;() function call? The Switch can be seen turning on and off with every tap. There has to be a &lt;strong&gt;setState&lt;/strong&gt;() function being called?! Well yes, yes there is. Look at the second screenshot below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2ARTnuAblqpfzLIUKug-FL2Q.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2ARTnuAblqpfzLIUKug-FL2Q.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foxeit04gugyofvb40mct.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foxeit04gugyofvb40mct.png" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4164%2F1%2A-FNUGshAaxnI1FydZmLu8Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4164%2F1%2A-FNUGshAaxnI1FydZmLu8Q.png" alt="[dev_settings.dart](https://github.com/Andrious/fluttery_stocks/blob/2f274955807d7ec7009c8170b7a41e5aaf8c22f9/lib/src/app/view/dev_settings.dart#L56) and [dev_tools_settings.dart](https://github.com/Andrious/fluttery_stocks/blob/1f9c1136a1d30fcee979d891d553ed3d29530d14/lib/src/app/controller/dev_tools_settings.dart#L149)" width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The second screenshot above is of the setter, &lt;em&gt;showPreformanceOverlay&lt;/em&gt;, found in the controller, &lt;em&gt;DevTools&lt;/em&gt;. There you see the new Switch value being received and recorded (true equals ‘on’ and false equals ‘off’). However, you also see a &lt;strong&gt;setState&lt;/strong&gt;() function call! When a controller is taken in by the StateX object, it can do whatever a State object can do…and more. The controller, &lt;em&gt;DevTools&lt;/em&gt;, extends from another class found in the Fluttery Framework called, StateXController.&lt;/p&gt;

&lt;p&gt;class DevTools extends StateXController {&lt;/p&gt;

&lt;p&gt;The DevTools class was instantiated and passed to the State object’s parent constructor, remember? It now has access to that State object and all its capabilities. Below, that one line is commented out and the program runs again. It reveals that this access is indeed true. The switch continues to be turned on and off, however, nothing appears to be happening. That’s because the screen simply hasn’t been refreshed — the widgets involved have not been rebuilt. In other words, the State object’s &lt;strong&gt;setState&lt;/strong&gt;() function hasn’t been called again — through its controller, &lt;em&gt;DevTools&lt;/em&gt;. We’re failing in our State Management duties. However, the performance overlay is indeed on when returning to the app’s home screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4v3dzer0hsz8lxq0568t.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4v3dzer0hsz8lxq0568t.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4184%2F1%2ATvmp7tINceKTQ2jtn86jEQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4184%2F1%2ATvmp7tINceKTQ2jtn86jEQ.png" alt="[dev_tools_settings.dart](https://github.com/Andrious/fluttery_stocks/blob/1f9c1136a1d30fcee979d891d553ed3d29530d14/lib/src/app/controller/dev_tools_settings.dart#L149)" width="800" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Keeping It Flutter
&lt;/h2&gt;

&lt;p&gt;Note, how I ‘kept it Flutter,’ with a separate subclass derived from the class, &lt;em&gt;StateXController&lt;/em&gt;, yet using the very same function name, &lt;strong&gt;setState&lt;/strong&gt;()? It simply calls the original &lt;strong&gt;setState&lt;/strong&gt;() function in a State object! All the packages on that list are doing the same thing. Note, some are even calling the &lt;strong&gt;markNeedsBuild&lt;/strong&gt;() function deeper in the Flutter framework itself to achieve the same thing. Something I chose not to do.&lt;/p&gt;

&lt;p&gt;That function resides in the Element class, and personally, that’s too deep in Flutter’s own framework. It’s in the realm where the Google engineers only play. The &lt;strong&gt;markNeedsBuild&lt;/strong&gt;() function is not part of the public API like &lt;strong&gt;setState&lt;/strong&gt;() — it’s the &lt;strong&gt;setState&lt;/strong&gt;() function that calls the &lt;strong&gt;markNeedsBuild&lt;/strong&gt;() function. Frankly, there‘s the chance that the &lt;strong&gt;markNeedsBuild&lt;/strong&gt;() function will go away a few years from now when they release Flutter 7.0 for example. Like any shop, Google will want its software to easily evolve and has only designated the &lt;strong&gt;setState&lt;/strong&gt;() function to be used when notifying Flutter of a change-in-state.&lt;/p&gt;

&lt;p&gt;Again, those other packages up on that list are using completely different paradigms to perform their State Management (i.e. to call &lt;strong&gt;setState&lt;/strong&gt;() in some State object) using completely different function names.&lt;/p&gt;

&lt;p&gt;Keep it Flutter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2560%2F1%2AfaG9vcUechxFD4UaaJbL-w.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2560%2F1%2AfaG9vcUechxFD4UaaJbL-w.gif" alt="[Jurassic Park (1993)](https://imgur.com/8hFBPQB)" width="1024" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Back to Fluttery. Note, these SOC’s (State Object Controllers) can be assigned, to any number of StateX objects throughout the lifetime of a Flutter app. For example, with each new StateX object (i.e. with each successive screen), a controller can be shared among them working with a particular State object before retreating back to the previous State object when that screen closes. Sure, Flutter’s State objects are to retain the state of the app, but now you have a StateXController object providing steadfast logic, and indeed, managing that state. The graphic below illustrates this “Last In First Out” (LIFO) relationship that occurs when a SOC is shared among progressive and then receding Flutter screens.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flvd2t86qgwjxlrtesxgw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flvd2t86qgwjxlrtesxgw.png" alt="State objects can share a Controller" width="262" height="286"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Further, your StateX object is allowed to take in as many controllers as you like. Each controller can be responsible for a particular functionality — ready to react to the many events that originate from that StateX object. See the graphic below. This ability encourages modular programming and allows for parallel development. Very nice.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffngq90su060m1uzytzp1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffngq90su060m1uzytzp1.png" alt="A State object can have many Controllers" width="240" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Developing Your Tools
&lt;/h2&gt;

&lt;p&gt;By the way, I should explain how those development tools are then displayed to you after you’ve selected one or more. In Flutter, rebuilding that screen full of Switch widgets isn’t enough. Yes, that’ll show the switch has changed, but nothing else would happen. You would have to also render the whole app over again! More accurately, call the &lt;strong&gt;setState&lt;/strong&gt;() function of the app’s first State object. With me so far? I’m keeping it Flutter.&lt;/p&gt;

&lt;p&gt;There’s a StateX object that’s the first State object or root State object for your app when using the Fluttery Framework. And in this case, we have to call its &lt;strong&gt;setState&lt;/strong&gt;() function to now display that Performance Overlay for example. Let’s show you how that works. However, I bet you’ve already got a good guess…if you know Flutter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F17r5gq6jwdhbu3uvasty.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F17r5gq6jwdhbu3uvasty.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4184%2F1%2Advp18LZHbCmU1cIQ7UbYpw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4184%2F1%2Advp18LZHbCmU1cIQ7UbYpw.png" alt="[home_stocks_view.dart](http://dev_tools_settings.dart)" width="800" height="505"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The screenshot above shows part of the Drawer widget displaying the option, &lt;em&gt;Debug Tools&lt;/em&gt;. Again, it’s a controller (this one is called StockHomeController*)* that handles things if the option is tapped on. Unbeknownst to you, that controller calls the controller, &lt;em&gt;DevTools&lt;/em&gt;, to bring up that screen of switches —thus deligating the work among different controllers and keeping it modular. See the first screenshot below.&lt;/p&gt;

&lt;p&gt;Note, that ‘Debug Tools’ option will not appear if the app is released into production (see above) courtesy of the Flutter Framework’s static getter, &lt;em&gt;App.inDebugger&lt;/em&gt; (also App.inDebugMode). This Fluttery Framework library package doesn’t just provide a means for State Management. It’s a framework! Frameworks are supposed to make development a little easier. Anyway, the majority of Flutter’s development tools aren’t available in Production anyway — why confuse the user with such an option?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feq4revzwunemloubi1a6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feq4revzwunemloubi1a6.png" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5f7grpome2bdnqxua6mo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5f7grpome2bdnqxua6mo.png" width="800" height="505"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4180%2F1%2A7lHBP4mlQJabN6q4JdRoHQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4180%2F1%2A7lHBP4mlQJabN6q4JdRoHQ.png" alt="[dev_tools_settings.dart](https://github.com/Andrious/fluttery_stocks/blob/1f9c1136a1d30fcee979d891d553ed3d29530d14/lib/src/app/controller/dev_tools_settings.dart#L11) and [dev_tools_settings.dart](https://github.com/Andrious/fluttery_stocks/blob/1f9c1136a1d30fcee979d891d553ed3d29530d14/lib/src/app/controller/dev_tools_settings.dart#L40) and [dev_tools_settings.dart](https://github.com/Andrious/fluttery_stocks/blob/1f9c1136a1d30fcee979d891d553ed3d29530d14/lib/src/app/controller/dev_tools_settings.dart#L7)" width="800" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember to tap on the screenshots for a closer look. If you’re on your phone, you can then use two fingers to zoom in even further.&lt;/p&gt;

&lt;p&gt;After the ‘Performance Overlay’ switch is turned on and the user closes that window, the DevTools Controller calls the &lt;strong&gt;setState&lt;/strong&gt;() from its property variable, &lt;em&gt;_state&lt;/em&gt;. See the second screenshot above. The third screenshot above highlights where that variable is initialized and what it is assigned to. It’s assigned the app’s State object (the first State object), and it’s assigned in the controller’s &lt;strong&gt;initState&lt;/strong&gt;() function. Now, guess where that &lt;strong&gt;initState&lt;/strong&gt;() function is called.&lt;/p&gt;

&lt;p&gt;It's called by the StateX object, &lt;em&gt;_StockSettingsState&lt;/em&gt;, in its own &lt;strong&gt;initState&lt;/strong&gt;() function. Remember, the DevTools controller was passed to that StateX object’s parent class constructor. Not only does the controller now have access to that StateX object and all its capabilities, but that StateX object now has access to that controller…and all its functions.&lt;/p&gt;

&lt;p&gt;As you know, in Flutter, when a State object is to be displayed for the first time (i.e. before it calls its &lt;strong&gt;build&lt;/strong&gt;() function for the first time) its &lt;strong&gt;initState&lt;/strong&gt;() function is first called. The same, of course, is true for any StateX object in the Fluttery Framework. When a StateX object calls its &lt;strong&gt;initState&lt;/strong&gt;() function, any StateXController(s) taken in by that time will have their own &lt;strong&gt;initState&lt;/strong&gt;() functions called as well. Easy peasy. These SOC’s (State Object Controllers) share some of the same functions as their associated StateX object making for more efficient development frankly. That’ll be demonstrated in articles to come.&lt;/p&gt;

&lt;p&gt;See how this all comes together? Notice how this framework behaves like Flutter because it was written to behave like Flutter? When it comes to State Management, things appear to be working out just fine, don’t they?&lt;/p&gt;

&lt;h2&gt;
  
  
  State and Control
&lt;/h2&gt;

&lt;p&gt;And that’s about it. It’s those two classes, &lt;em&gt;StateX *and *StateXController&lt;/em&gt;, that make up the core of the Fluttery Framework. Any additional classes introduced to you in this framework will be a subclass of one of these two classes— one of which, of course, is the subclass of Flutter’s own State class.&lt;/p&gt;

&lt;h2&gt;
  
  
  In The Beginning
&lt;/h2&gt;

&lt;p&gt;An example of this is seen in how a typical Flutter app starts up when using the Fluttery Framework. Let’s finish this first article in the series by examining the Stocks example app’s main.dart file. As you can see in the screenshot below, there really isn’t much to it. That’s by design. The remaining source code is safely inside the &lt;strong&gt;src&lt;/strong&gt; folder. The &lt;strong&gt;runapp&lt;/strong&gt;() function only requires one lone Widget as a parameter. The app really begins with that one lone Widget called, MyApp.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4166%2F1%2AJ7-8wIFW7BnBz8cceSqyjQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4166%2F1%2AJ7-8wIFW7BnBz8cceSqyjQ.png" alt="[main.dart](https://github.com/Andrious/fluttery_stocks/blob/1f9c1136a1d30fcee979d891d553ed3d29530d14/lib/main.dart#L1)" width="800" height="230"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The StatefulWidget, &lt;em&gt;MyApp&lt;/em&gt;, has a parent class called, &lt;em&gt;AppStatefulWidget&lt;/em&gt;. Tap on the first screenshot below for a closer look. Pretty straightforward. It’s the widget I recommend you pass to the &lt;strong&gt;runApp&lt;/strong&gt;() function because it then calls its &lt;strong&gt;createAppState&lt;/strong&gt;() function to create the Fluttery Framework’s AppState object. That’s the ‘first’ State object for your Flutter app and, of course, is a subclass of the StateX class. You can see in the second screenshot below, it has a named parameter called, controller.&lt;/p&gt;

&lt;p&gt;Keeping it Flutter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vlia973cmpkuv1nfrc9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vlia973cmpkuv1nfrc9.png" width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuuvook9vuob9kld45r6t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuuvook9vuob9kld45r6t.png" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4178%2F1%2A-tcBEM9kJg-Y03Z6Ro6zug.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4178%2F1%2A-tcBEM9kJg-Y03Z6Ro6zug.png" alt="[stocks.dart](https://github.com/Andrious/fluttery_stocks/blob/1f9c1136a1d30fcee979d891d553ed3d29530d14/lib/src/app/view/stocks.dart#L5) and [stocks.dart](https://github.com/Andrious/fluttery_stocks/blob/1f9c1136a1d30fcee979d891d553ed3d29530d14/lib/src/app/view/stocks.dart#L14) and [app_stocks_controller.dart](https://github.com/Andrious/fluttery_stocks/blob/1f9c1136a1d30fcee979d891d553ed3d29530d14/lib/src/app/controller/app_stocks_controller.dart#L6)" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The third screenshot is that of the AppStocks class — a subclass of the AppController class which, in turn, is a subclass of the class, StateXController. Both the AppState and AppController class have their specialized roles to play when making your Flutter app development that much easier and that much more productive. I mean, tap on the caption under the second screenshot below, and it’ll take you to the Fluttery Framework’s GitHub repository. There, you’ll see how many parameters the AppState class has available to you to define the ‘look and feel’ of your next Flutter app. The source code is all documented. You can figure it out. But don’t worry, we’re just getting started with this series of articles.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuuvook9vuob9kld45r6t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuuvook9vuob9kld45r6t.png" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4000%2F1%2AHr9yW7KlH74pSlkC9I6AfQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4000%2F1%2AHr9yW7KlH74pSlkC9I6AfQ.png" alt="[stocks.dart](https://github.com/Andrious/fluttery_stocks/blob/1f9c1136a1d30fcee979d891d553ed3d29530d14/lib/src/app/view/stocks.dart#L14) and [app_state.dart](https://github.com/AndriousSolutions/fluttery_framework/blob/master/lib/src/view/app_state.dart#L45)" width="800" height="505"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  State My Admittance
&lt;/h2&gt;

&lt;p&gt;Finally, as you may have long realized by now, I really shouldn’t be explicitly comparing this framework to the Dart packages in that list above. Those are library packages simply offering an approach to State Management, this is much more…it’s a Framework.&lt;/p&gt;

&lt;p&gt;The classes, &lt;em&gt;StateX *and *StateXController&lt;/em&gt;, that make up the core of the Fluttery Framework, would be a more accurate comparison to that list. I wrote the &lt;a href="https://pub.dev/packages/state_extended" rel="noopener noreferrer"&gt;state_extended&lt;/a&gt;package to more effectively and more efficiently implement State Management with Flutter; like Flutter. It just happens that this framework uses it as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F1%2AuabUf2zyzHl8m4Ec5QQQkg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F1%2AuabUf2zyzHl8m4Ec5QQQkg.png" alt="[Free Medium article on StateX](https://andrious.medium.com/statex-60bc9957bf20)" width="800" height="222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s the Fluttery Framework that implements the rest. That is, it implements things that should come with your app in the first place — standard functions and features to be found in any production release, Frameworks are to assist developers in building their apps — make development that much faster and that much easier. Frameworks do the ‘heavy lifting’ and provide standard capabilities reliably and consistently so the developer doesn’t have to every time. They’re to provide aspects of development we developers are guilty of not considering as much as we should. Error handling comes to mind. Unfortunately, when it comes to error handling, our priority is to write code that works —we tend not to consider what should happen if something goes wrong. This series will address all of that in time.&lt;/p&gt;

&lt;p&gt;Until then, I invite you to download the example app, &lt;a href="https://github.com/Andrious/fluttery_stocks" rel="noopener noreferrer"&gt;*Stocks&lt;/a&gt;*, and take the Flutter Framework for a test drive. ‘Keeping it clean,’ ‘Keeping it simple’ and ‘Keeping it Flutter’ has made my projects adaptive, scalable, and maintainable. True, there are a lot of Flutter developers out there using the top-three State Management library packages up on that list.&lt;/p&gt;

&lt;p&gt;I can only assume they just don’t know about this framework yet. ;)&lt;/p&gt;

&lt;p&gt;Cheers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/p/9de112c2d85c/" rel="noopener noreferrer"&gt;→ More Stories by Greg Perry&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>programming</category>
    </item>
    <item>
      <title>A Fluttery Digest</title>
      <dc:creator>Greg Perry</dc:creator>
      <pubDate>Wed, 29 Jan 2025 16:22:52 +0000</pubDate>
      <link>https://dev.to/andrious/a-fluttery-digest-2kb8</link>
      <guid>https://dev.to/andrious/a-fluttery-digest-2kb8</guid>
      <description>&lt;p&gt;&lt;em&gt;A compilation of Fluttery Framework Articles&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  It’s Not Flutter
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6aylsylx4kgwrqvh7ux7.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6aylsylx4kgwrqvh7ux7.jpeg" width="320" height="214"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://dev.to/andrious/its-not-flutter-27co"&gt;It’s Not Flutter&lt;/a&gt;



&lt;h2&gt;
  
  
  Little More Efficient
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feotxxo7f5h0brcisdmxx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feotxxo7f5h0brcisdmxx.png" width="320" height="214"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://dev.to/andrious/little-more-efficient-5a71"&gt;Little More Efficient&lt;/a&gt;



&lt;h2&gt;
  
  
  Little More Control
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3kdnmmin30gwsorcd750.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3kdnmmin30gwsorcd750.png" width="320" height="214"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://dev.to/andrious/little-more-control-3o3b"&gt;Little More Control&lt;/a&gt;



&lt;h2&gt;
  
  
  Little More Error Handling
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fppcf6pptq1ahrg4749cs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fppcf6pptq1ahrg4749cs.png" width="320" height="214"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://dev.to/andrious/little-more-error-handling-i36"&gt;Little More Error Handling&lt;/a&gt;



&lt;h2&gt;
  
  
  Little More Life Cycle Handling
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ft0b8e5v0rut4v8sqte.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ft0b8e5v0rut4v8sqte.png" width="320" height="214"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://dev.to/andrious/little-more-life-cycle-handling-1fp0"&gt;Little More Life Cycle Handling&lt;/a&gt;



&lt;h2&gt;
  
  
  Little More Adaptive
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frarery11w58ktwdokpsa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frarery11w58ktwdokpsa.png" width="320" height="214"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://dev.to/andrious/little-more-adaptive-5c3k"&gt;Little More Adaptive&lt;/a&gt;



&lt;h2&gt;
  
  
  The Fluttery Framework
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F93edy7vg16s9en306k6y.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F93edy7vg16s9en306k6y.jpeg" width="320" height="214"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://dev.to/andrious/the-fluttery-framework-3kbn"&gt;The Fluttery Framework&lt;/a&gt;



</description>
      <category>flutter</category>
      <category>programming</category>
    </item>
    <item>
      <title>It’s Not Flutter</title>
      <dc:creator>Greg Perry</dc:creator>
      <pubDate>Fri, 06 Dec 2024 19:05:02 +0000</pubDate>
      <link>https://dev.to/andrious/its-not-flutter-27co</link>
      <guid>https://dev.to/andrious/its-not-flutter-27co</guid>
      <description>&lt;h2&gt;
  
  
  It’s Not Flutter
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Keep It Simple, Keep It Flutter&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I don’t use BLoC. I always felt using a Stream was a bit of overkill to call a &lt;strong&gt;setState&lt;/strong&gt;() function whenever a change-in-state. Yes, it’s a means to do so independent of the Widget tree, but Streams were meant for streams of data not for event handling. However, my real issue is with the ‘Provider Model’ design pattern used by BLoC.&lt;/p&gt;

&lt;p&gt;It’s not Flutter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffgi0obxbuewt18lz9xuu.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffgi0obxbuewt18lz9xuu.jpeg" width="422" height="390"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://dev.to/andrious"&gt;Other stories by Greg Perry&lt;/a&gt;



&lt;p&gt;In other words, it doesn’t resemble the design pattern taken up by the Flutter framework itself. In truth, I‘ve no real issue with the Provider Model design pattern. It’s a proven approach conceived back in 2005 by Microsoft with the release of ASP.NET 2.0. It’s just not the design pattern found in Flutter.&lt;/p&gt;

&lt;p&gt;Like any good framework, Flutter doesn’t impose its chosen pattern allowing developers to implement BLoC, RiverPod, etc. The design pattern they use is very familiar to developers. However, it’s my opinion using one that resembles the underlying framework will make developing and maintaining an app that much easier, that much more efficient and effective.&lt;/p&gt;

&lt;p&gt;The design pattern taken up by the Flutter framework is like the MVC design pattern, but more like the &lt;a href="https://softwareengineering.stackexchange.com/questions/207620/what-are-the-downfalls-of-mvc#answer-207672" rel="noopener noreferrer"&gt;PAC&lt;/a&gt; (&lt;a href="http://en.wikipedia.org/wiki/Presentation%E2%80%93abstraction%E2%80%93control" rel="noopener noreferrer"&gt;Presentation-Abstraction-Control&lt;/a&gt;) design pattern. Flutter’s emphasis is more on the Interface (Presentation), a little on the logic and event handling (Controller), and less on data (Model). In Flutter, data is an Abstraction. It can be anything; It can be nothing. It’s implementation is left to the developer.&lt;/p&gt;

&lt;p&gt;Further, Google engineers have only issued a Controller class to a select number of Widgets so far (see Google search below). With these Widgets, their &lt;strong&gt;build&lt;/strong&gt;() functions will work the interface while their Controller class will work the widget’s data, logic and or event handling.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.google.com/search?q=site%3Aflutter.dev+insubject%3A%22controller%22" rel="noopener noreferrer"&gt;&lt;em&gt;site:flutter.dev insubject:”controller”&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article, a controller is supplied to the State class. That Controller will then have a reference to the State object allowing for a very powerful capability. A capability coveted by all those State Management solutions out there: Allowing for the change-in-state to be conveyed at any time and from anywhere. See below.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;controller.state.setState((){});&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The class, &lt;em&gt;StateX&lt;/em&gt;, will be introduced in this article — it comes from the package, &lt;a href="https://pub.dev/packages/state_extended" rel="noopener noreferrer"&gt;&lt;em&gt;state_extended&lt;/em&gt;&lt;/a&gt;. Its constructor can take in a ‘State Object Controller’ and will then reference that Controller using the property, &lt;em&gt;controller&lt;/em&gt;. See the screenshot below for an example.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4izmvqbaotwm1f6eet81.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4izmvqbaotwm1f6eet81.png" width="800" height="693"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/flutter_weather/blob/29b0e2b7649ca000e09e1807026867d0697b260c/lib/main/view/weather_page.dart#L13" rel="noopener noreferrer"&gt;weather_page.dart&lt;/a&gt;



&lt;p&gt;This separate Controller class now has a reference to a State object and all that that entails. Make up your own State Object Controller, by extending the class, &lt;em&gt;StateXController&lt;/em&gt;, and further receive a variety of properties and capabilities:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;con.state; &lt;strong&gt;The current State object assigned to the Controller.&lt;/strong&gt;&lt;br&gt;
con.initAsync(); &lt;strong&gt;Run asynchronous operations before State build() runs.&lt;/strong&gt;&lt;br&gt;
con.rootState; &lt;strong&gt;The 'AppState' object. The app's first State object.&lt;/strong&gt;&lt;br&gt;
con.firstState; &lt;strong&gt;The first State object ever assigned to this Controller.&lt;/strong&gt;&lt;br&gt;
con.dependOnInheritedWidget(context); &lt;strong&gt;Register widget to InheritedWidget.&lt;/strong&gt;&lt;br&gt;
con.dataObject; &lt;strong&gt;Optional 'data object' passed down through the app.&lt;/strong&gt;&lt;br&gt;
con.inDebugMode; &lt;strong&gt;Boolean if running in Production or not.&lt;/strong&gt;&lt;br&gt;
con.lastContext; &lt;strong&gt;The lastest context object in the Widget tree.&lt;/strong&gt;&lt;br&gt;
con.lastState; &lt;strong&gt;The latest State object assigned to this Controller.&lt;/strong&gt;&lt;br&gt;
con.forEachState((state){}); &lt;strong&gt;Loop through its State objects.&lt;/strong&gt;&lt;br&gt;
con.notifyClients(); &lt;strong&gt;Call the built-in InheritedWidget.&lt;/strong&gt;&lt;br&gt;
con.ofState&amp;lt;_MainPageState&amp;gt;(); &lt;strong&gt;Returns specified State object.&lt;/strong&gt;&lt;br&gt;
con.setState((){}); &lt;strong&gt;Calls current State object's setState() function.&lt;/strong&gt;&lt;br&gt;
con.setBuilder(); &lt;strong&gt;setState() will rebuild the Widget from this builder.&lt;/strong&gt;&lt;br&gt;
con.stateOf(); &lt;strong&gt;Returns the StatefulWidget's State object.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Further note, it’s a Mixin that supplies much of this functionality to these Controllers (see below). If you don’t want to use the class, &lt;em&gt;StateX,&lt;/em&gt; you can use the Mixin instead.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1mowa12du7ku4o0n1dp9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1mowa12du7ku4o0n1dp9.png" width="800" height="243"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/f7aa762b7afc1b47412df4718d0c242f27875af1/lib/part14_set_state_mixin.dart#L7" rel="noopener noreferrer"&gt;part14_set_state_mixin.dart&lt;/a&gt;



&lt;p&gt;I‘ve migrated the ‘weather’ example app from BloC to this ‘MVC-more-like-PAC’ approach using the &lt;a href="https://pub.dev/packages/fluttery_framework" rel="noopener noreferrer"&gt;Fluttery Framework&lt;/a&gt; package. In this article, I’ll describe the differences between these two implementations.&lt;/p&gt;

&lt;p&gt;Both GitHub repositories are available below:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/felangel/bloc/blob/master/examples/flutter_weather/" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub - bloc/examples/flutter_weather&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/Andrious/flutter_weather" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub - Andrious/flutter_weather&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Control Your Build
&lt;/h2&gt;

&lt;p&gt;Below is a side-by-side comparison of the example app’s Settings page. The first screenshot below is the original BLoC version with its &lt;strong&gt;BlocBuilder&lt;/strong&gt;() function while the second screenshot uses the StateXController class, and its &lt;strong&gt;setBuilder&lt;/strong&gt;() function. Both are functions that rebuild with a &lt;strong&gt;setState&lt;/strong&gt;() function call leaving the rest of the interface untouched.&lt;/p&gt;

&lt;p&gt;Note how some of the logic (how values are conceived) is more readily visible in the BLoC version. For example, in the first screenshot, the property, &lt;em&gt;WeatherState&lt;/em&gt;, is exposed in the interface while the Controller version in the second screenshot only displays designated properties and necessary functions from the Controller object, &lt;em&gt;_con.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Supplying such a layer of abstraction encourages better modularity, better adaptation, better scalability, and generally better maintenance of the software. It provides the interface that's needed without revealing how it’s provided. That way, in the future, you can change how that’s done with ease without changing one bit of the interface.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F69sv0mcunkxbodvhvcdq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F69sv0mcunkxbodvhvcdq.gif" alt="CtoF" width="740" height="1558"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fht80z679eusr4db4g5jp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fht80z679eusr4db4g5jp.png" width="800" height="691"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/felangel/bloc/blob/f951eef84e4e740697b712ff3e1cf244eea3a1e6/examples/flutter_weather/lib/settings/view/settings_page.dart#L15" rel="noopener noreferrer"&gt;settings_page.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcjzgu30zpqfis0wrf6r2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcjzgu30zpqfis0wrf6r2.png" width="800" height="697"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/flutter_weather/blob/29b0e2b7649ca000e09e1807026867d0697b260c/lib/main/view/settings/settings_page.dart#L24" rel="noopener noreferrer"&gt;settings_page.dart&lt;/a&gt;



&lt;h2&gt;
  
  
  Inherited Builds
&lt;/h2&gt;

&lt;p&gt;In the BLoC version, the BlocProvider implements an InheritedWidget and makes the app’s remaining interface, &lt;em&gt;WeatherAppView&lt;/em&gt;, a dependency of that InheritedWidget — a means to ‘rebuild’ that Widget again and again when necessary. See the first screenshot below.&lt;/p&gt;

&lt;p&gt;In the second screenshot below, the &lt;em&gt;StateX&lt;/em&gt; version utilizes an InheritedWidget as well. However, the widget, &lt;em&gt;WeatherAppView&lt;/em&gt;, is replaced by the State object, &lt;em&gt;_WeatherAppState&lt;/em&gt;, that defines the overall ‘look and behavior’ of the app.&lt;/p&gt;

&lt;p&gt;This may be an unfair comparison at this point, as the &lt;a href="https://pub.dev/packages/fluttery_framework" rel="noopener noreferrer"&gt;Fluttery Framework&lt;/a&gt; is designed to produce ‘production-ready’ apps while the BLoC version is merely a very simple example app. Therefore, I’ll limit this article to comparing the ‘differences’ made to conceive the same interface and behavior. For more information on the Fluttery Framework, see the &lt;a href="https://andrious.medium.com/the-little-more-series-94b0a9c6cd25" rel="noopener noreferrer"&gt;‘Little More’ Series&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F97ueczps6jfvxgfmqvqc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F97ueczps6jfvxgfmqvqc.png" width="800" height="695"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/felangel/bloc/blob/f951eef84e4e740697b712ff3e1cf244eea3a1e6/examples/flutter_weather/lib/app.dart#L8" rel="noopener noreferrer"&gt;app.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgmgjz7wcc14o3mgzkv8j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgmgjz7wcc14o3mgzkv8j.png" width="800" height="694"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/flutter_weather/blob/29b0e2b7649ca000e09e1807026867d0697b260c/lib/app/view/weather_app.dart#L11" rel="noopener noreferrer"&gt;weather_app.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2Agu21FkxMLkWyhTjvZM4XEg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2Agu21FkxMLkWyhTjvZM4XEg.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Control is Everything
&lt;/h2&gt;

&lt;p&gt;Back to the BLoC version, as a dependency, the &lt;em&gt;WeatherAppView&lt;/em&gt; widget will be rebuilt again if and when the value, &lt;em&gt;toColor&lt;/em&gt;, has changed. You can see that highlighted in the first screenshot below. Again, the logic is exposed in the interface.&lt;/p&gt;

&lt;p&gt;The next two screenshots below are from the Fluttery version of the app but are not the corresponding interface. Instead, it’s of the controller, &lt;em&gt;WeatherController&lt;/em&gt;. That’s because that specific logic is found in the Controller and not in the interface. Again, it is the Controller that determines what widget is rebuilt and why.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvxn4qnhe2tn5cbwx86yp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvxn4qnhe2tn5cbwx86yp.png" width="800" height="652"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/felangel/bloc/blob/f951eef84e4e740697b712ff3e1cf244eea3a1e6/examples/flutter_weather/lib/app.dart#L22" rel="noopener noreferrer"&gt;app.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faqgu8dyuaz8uro8tu766.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faqgu8dyuaz8uro8tu766.png" width="800" height="698"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/flutter_weather/blob/29b0e2b7649ca000e09e1807026867d0697b260c/lib/main/controller/weather_controller.dart#L115" rel="noopener noreferrer"&gt;weather_controller.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh93njv2q1nf7s71qrcay.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh93njv2q1nf7s71qrcay.png" width="800" height="693"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/flutter_weather/blob/29b0e2b7649ca000e09e1807026867d0697b260c/lib/main/controller/weather_controller.dart#L136" rel="noopener noreferrer"&gt;weather_controller.dart&lt;/a&gt;



&lt;p&gt;In the BLoC version, the class, &lt;em&gt;WeatherCubit&lt;/em&gt;, is somewhat equivalent to the class, &lt;em&gt;WeatherController,&lt;/em&gt; in the Fluttery version. Both fetch new Weather information, and both deal directly with the data source involved.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flynf0oodfqt16bq0vl7u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flynf0oodfqt16bq0vl7u.png" width="800" height="688"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/felangel/bloc/blob/f951eef84e4e740697b712ff3e1cf244eea3a1e6/examples/flutter_weather/lib/weather/cubit/weather_cubit.dart#L11" rel="noopener noreferrer"&gt;weather_cubit.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3krfxmdt8h56yvt8vxxn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3krfxmdt8h56yvt8vxxn.png" width="800" height="700"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/flutter_weather/blob/29b0e2b7649ca000e09e1807026867d0697b260c/lib/main/controller/weather_controller.dart#L12" rel="noopener noreferrer"&gt;weather_conroller.dart&lt;/a&gt;



&lt;h2&gt;
  
  
  A Single Simple Solution
&lt;/h2&gt;

&lt;p&gt;Note, how the Controller uses a factory constructor to make only one instance of this class. This implements the Singleton design pattern and is, more often than not, very suitable for the role of a State Object Controller: It retains ‘a running account’ of the app’s state, its logic, and the current data involved. Further, it makes that one instance readily available throughout your app if you like using very little boilerplate code. Much of what makes up the Provider Model, is instead achieved by a factory constructor. Keep it simple. Keep it Flutter.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;context.read&amp;lt;Weatheruit&amp;gt;.refreshWeather();&lt;/code&gt; vs.&lt;br&gt;
 &lt;code&gt;WeatherController().refreshWeather();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Going back to the example app comparisons. You can see in the first screenshot below, how the BLoC version relies on the Widget tree to retrieve the one instance of &lt;em&gt;WeatherCubit&lt;/em&gt;. This is so as to call its functions, &lt;strong&gt;refreshWater&lt;/strong&gt;() and &lt;strong&gt;fetchWeather&lt;/strong&gt;(). The State object in the second screenshot below merely uses the local variable, &lt;em&gt;con&lt;/em&gt;. It originally came about from the constructor call, &lt;strong&gt;WeatherController&lt;/strong&gt;().&lt;/p&gt;

&lt;p&gt;&lt;code&gt;extension ReadContext on BuilldContext {&lt;br&gt;
 T read&amp;lt;T&amp;gt;() { return Provider.of&amp;lt;T&amp;gt;(this, listen: false); }&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmtqdvpg0aswtrx0pyp5d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmtqdvpg0aswtrx0pyp5d.png" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/felangel/bloc/blob/f951eef84e4e740697b712ff3e1cf244eea3a1e6/examples/flutter_weather/lib/weather/view/weather_page.dart#L30" rel="noopener noreferrer"&gt;weather_page.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7sryg4xqp1ra5lp9hrax.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7sryg4xqp1ra5lp9hrax.png" width="800" height="703"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/flutter_weather/blob/29b0e2b7649ca000e09e1807026867d0697b260c/lib/main/view/weather_page.dart#L53" rel="noopener noreferrer"&gt;weather_page.dart&lt;/a&gt;



&lt;p&gt;The same approach is found in the Settings page respectively.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzs1yhjxiwhrazhniiumf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzs1yhjxiwhrazhniiumf.png" width="800" height="691"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/felangel/bloc/blob/f951eef84e4e740697b712ff3e1cf244eea3a1e6/examples/flutter_weather/lib/settings/view/settings_page.dart#L15" rel="noopener noreferrer"&gt;settings_page.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgdp9kt7bes1b2jneke0q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgdp9kt7bes1b2jneke0q.png" width="800" height="697"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/flutter_weather/blob/29b0e2b7649ca000e09e1807026867d0697b260c/lib/main/view/settings/settings_page.dart#L24" rel="noopener noreferrer"&gt;settings_page.dart&lt;/a&gt;



&lt;h2&gt;
  
  
  In The Beginning
&lt;/h2&gt;

&lt;p&gt;Note how the WeatherCubit class is defined nowhere near where it is first used. This practice is a throwback to when the Provider design pattern was first introduced with ASP.Net 2.0. Generally, everything was defined at the start of the app.&lt;/p&gt;

&lt;p&gt;In the BLoC example app, the &lt;em&gt;BlocProvider&lt;/em&gt; will only create an instance of the WeatherCubit class when it’s first required. When instantiated, it’s then stored in an internal variable, &lt;em&gt;_value&lt;/em&gt;(second screenshot below). In the first screenshot below, the WeatherCubit class is defined at the start of the app. For this app, it is only stored in the variable, &lt;em&gt;_value&lt;/em&gt;, (making for a pseudo-Singleton approach) when first required to determine the app’s background color (third screenshot below).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc9776cdoyrmiszzjoi9p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc9776cdoyrmiszzjoi9p.png" width="800" height="695"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/felangel/bloc/blob/f951eef84e4e740697b712ff3e1cf244eea3a1e6/examples/flutter_weather/lib/app.dart#L8" rel="noopener noreferrer"&gt;app.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhws8faxpu3qt2xg30c6d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhws8faxpu3qt2xg30c6d.png" width="800" height="648"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/rrousselGit/provider/blob/a689f406d2e937993de4ad9fa3028f126fab695e/packages/provider/lib/src/inherited_provider.dart#L690" rel="noopener noreferrer"&gt;inherited_provider.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fljtk0xy2qx6no22u5e0l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fljtk0xy2qx6no22u5e0l.png" width="800" height="652"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/felangel/bloc/blob/f951eef84e4e740697b712ff3e1cf244eea3a1e6/examples/flutter_weather/lib/app.dart#L22" rel="noopener noreferrer"&gt;app.dart&lt;/a&gt;



&lt;p&gt;In the Controller version, a WeatherController instance is only created when it’s first required as well. With its factory constructor, it is that instance that is then used throughout the app. Done.&lt;/p&gt;

&lt;p&gt;At the start of this example app, the *inTheme *clause is used to supply the color scheme — one of many options available to you when using Fluttery (see &lt;a href="https://andrious.medium.com/little-more-adaptive-8ef102ea1375" rel="noopener noreferrer"&gt;Little More Adaptive&lt;/a&gt;). In the second screenshot below, of course, it’s the same instance used to fetch the weather info.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7e4tnttfepzd681d7ba3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7e4tnttfepzd681d7ba3.png" width="800" height="694"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/flutter_weather/blob/29b0e2b7649ca000e09e1807026867d0697b260c/lib/app/view/weather_app.dart#L11" rel="noopener noreferrer"&gt;weather_app.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmrwotp2ty2uf00baxisy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmrwotp2ty2uf00baxisy.png" width="800" height="693"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/flutter_weather/blob/29b0e2b7649ca000e09e1807026867d0697b260c/lib/main/view/weather_page.dart#L13" rel="noopener noreferrer"&gt;weather_page.dart&lt;/a&gt;



&lt;h2&gt;
  
  
  The Hive Mind
&lt;/h2&gt;

&lt;p&gt;By default, the BLoC version uses a popular lightweight NoSQL database called &lt;a href="https://pub.dev/packages/hive" rel="noopener noreferrer"&gt;Hive&lt;/a&gt;. As such, working through the class, &lt;em&gt;WeatherCubit&lt;/em&gt;, the Weather object’s data is saved to this database assumingly to demonstrate that capability. Thus, I noted when restarting the app, it wouldn’t fetch that city’s current weather info., but simply retrieve the past data stored in the Hive database. It may make for an out-of-date weather reading, but again, it demonstrated that capability. In the video below, the weather is only updated with another explicit fetch of the data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A-tApvzqUL3WU_61vbBH0fQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A-tApvzqUL3WU_61vbBH0fQ.gif" width="1024" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxkgeuvh5b3qa7nzeaahf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxkgeuvh5b3qa7nzeaahf.png" width="800" height="695"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/felangel/bloc/blob/f951eef84e4e740697b712ff3e1cf244eea3a1e6/examples/flutter_weather/lib/main.dart" rel="noopener noreferrer"&gt;main.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpnxzfrgr6pvralvoqt6y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpnxzfrgr6pvralvoqt6y.png" width="800" height="681"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/felangel/bloc/blob/e2407caf46dd217535816889ea0e6791fdc4ab3c/packages/hydrated_bloc/lib/src/hydrated_bloc.dart#L114" rel="noopener noreferrer"&gt;hydrated_bloc.dart&lt;/a&gt;



&lt;p&gt;Fluttey doesn’t offer a database. Like Flutter, that’s left to the developer. As for the example app, I chose only to save the city name using the device’s stored-preferences infrastructure. The next time the app started up, that city name would be looked up again with the usual API call.&lt;/p&gt;

&lt;p&gt;In the first screenshot above, Felix chose to initialize the database at the beginning of the app. Again, a common practice in the past. The Fluttery version is more State-centric. The data source is only required in the State object, &lt;em&gt;_WeatherPageState&lt;/em&gt;, where data is retrieved (first screenshot below). Of course, in the second screenshot below, it is its Controller that takes care of all this. Because the Controller was passed into that State object (see line below), its &lt;strong&gt;initAsync&lt;/strong&gt;() function is called and performs the fetch. A spinner is displayed until that weather info is fetched from the Web service (see video below).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;_WeatherPageState() : super(controller: WeatherController()) {&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwxz57y2yns893nt6udkq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwxz57y2yns893nt6udkq.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn4t18aau11xble64unjt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn4t18aau11xble64unjt.png" width="800" height="700"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/46d143e5feb071bb68820e2eb8e28c79f384278c/lib/part01_statex.dart#L193" rel="noopener noreferrer"&gt;part01_statex.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvokm931dwh48k9ym6ejh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvokm931dwh48k9ym6ejh.png" width="800" height="699"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/flutter_weather/blob/29b0e2b7649ca000e09e1807026867d0697b260c/lib/main/controller/weather_controller.dart#L38" rel="noopener noreferrer"&gt;weather_controller.dart&lt;/a&gt;



&lt;p&gt;Again, I chose only to save the city name using the &lt;a href="https://pub.dev/packages/prefs" rel="noopener noreferrer"&gt;&lt;em&gt;Prefs&lt;/em&gt;&lt;/a&gt; package. It works with the plugin, &lt;a href="https://pub.dev/packages/shared_preferences" rel="noopener noreferrer"&gt;&lt;em&gt;shared_preferences&lt;/em&gt;&lt;/a&gt;. which, depending on the platform, wraps the NSUserDefaults (in iOS) and the SharedPreferences (in Android), to provide persistent storage.&lt;/p&gt;

&lt;p&gt;Let’s leave it there.&lt;/p&gt;

&lt;p&gt;Note, if this app supplied real-time forecasts, I’d use a Stream.&lt;/p&gt;

&lt;p&gt;Cheers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/andrious"&gt;→ Other Stories by Greg Perry&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>programming</category>
    </item>
    <item>
      <title>How To Use ChangeNotifier</title>
      <dc:creator>Greg Perry</dc:creator>
      <pubDate>Fri, 29 Nov 2024 16:59:26 +0000</pubDate>
      <link>https://dev.to/andrious/how-to-use-changenotifier-2enk</link>
      <guid>https://dev.to/andrious/how-to-use-changenotifier-2enk</guid>
      <description>&lt;h2&gt;
  
  
  How To Use ChangeNotifier
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;It can’t be used in certain cases. Not directly anyway.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Have you ever tried to use the ChangeNotifier as a Mixin on a State class? You can’t do it.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;class NotifierState extends State&amp;lt;NotifierWidget&amp;gt; with ChangeNotifier;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you try, your State class will no longer call its &lt;strong&gt;dispose&lt;/strong&gt;() method, and you need to call its &lt;strong&gt;dispose&lt;/strong&gt;() method to ‘clean’ things up in many cases. However, the ChangeNotifier is a Mixin with its own &lt;strong&gt;dispose&lt;/strong&gt;() method, and it doesn’t extend a parent class with a &lt;strong&gt;dispose&lt;/strong&gt;() function. Therefore, as you can see in the second screenshot below, its &lt;strong&gt;dispose&lt;/strong&gt;() method doesn’t have to call, super.&lt;strong&gt;dispose&lt;/strong&gt;(). It just won’t work as a Mixin on any class that has its own &lt;strong&gt;dispose&lt;/strong&gt;() method. However, there is a way to introduce a ChangeNotifier with a Mixin by doing it indirectly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fspe05z09tzonu7fy7nyq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fspe05z09tzonu7fy7nyq.png" width="800" height="654"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/flutter/flutter/blob/455be19d928fa8e0e5bb26904f2d0f57312794c6/packages/flutter/lib/src/foundation/change_notifier.dart#L137" rel="noopener noreferrer"&gt;change_notifier.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3f3ygcx7zkag3rfvyuv1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3f3ygcx7zkag3rfvyuv1.png" width="800" height="656"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/flutter/flutter/blob/455be19d928fa8e0e5bb26904f2d0f57312794c6/packages/flutter/lib/src/foundation/change_notifier.dart#L372" rel="noopener noreferrer"&gt;change_notifier.dart&lt;/a&gt;



&lt;p&gt;Supply the Mixin, &lt;em&gt;ImplNotifyListenersChangeNotifierMixin&lt;/em&gt;, to your State class, and place the method call, &lt;strong&gt;disposeChangeNotifier&lt;/strong&gt;(), to its &lt;strong&gt;dispose&lt;/strong&gt;() method. You‘ll then have a ChangeNotifier working with your State class.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  @override
  @mustCallSuper
  void dispose() {
    // Call the dispose of the implementation of Change Notifier
    disposeChangeNotifier();
    super.dispose();
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Grab a copy of this Mixin below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'package:flutter/material.dart';

import 'listenable_widget_builder.dart';

mixin ImplNotifyListenersChangeNotifierMixin {
  //

  // Instantiate the Change Notifier
  void initChangeNotifier() {
    _implChangeNotifier ??= ImplNotifyListenersChangeNotifier();
  }

  /// A flag. Instantiated Change Notifier
  bool get hasChangeNotifierImpl =&amp;gt; _implChangeNotifier != null;

  /// Don't forget to call dispose() function!
  void disposeChangeNotifier() {
    _implChangeNotifier?.dispose();
    _implChangeNotifier = null;
  }

  // Implementation of the ChangeNotifier
  ImplNotifyListenersChangeNotifier? _implChangeNotifier;

  /// Returns a widget from builder assuming the current object is a [Listenable]
  /// const SizedBox.shrink() otherwise
  Widget setBuilder(MaybeBuildWidgetType? builder) {
    // Ensure the ChangeNotifier is initialized
    initChangeNotifier();

    if (builder != null) {
      _widgetBuilderUsed = true;
    }
    return ListenableWidgetBuilder(
      listenable: _implChangeNotifier,
      builder: builder,
    );
  }

  /// A flag. Noting if the function above is ever used.
  bool get setBuilderUsed =&amp;gt; _widgetBuilderUsed;
  bool _widgetBuilderUsed = false;

  /// Whether any listeners are currently registered.
  bool get hasChangeListeners =&amp;gt; _implChangeNotifier?.hasChangeListeners ?? false;

  /// Call all the registered listeners.
  bool notifyListeners()  {
    final notify = _implChangeNotifier != null;
    if (notify) {
      _implChangeNotifier?.notifyListeners();
    }
    return notify;
  }

  /// Register a closure to be called when the object changes.
  bool addListener(VoidCallback listener) {
    final add = _implChangeNotifier != null;
    if (add) {
      _implChangeNotifier?.addListener(listener);
    }
    return add;
  }

  /// Remove a previously registered closure from the list of closures that are
  /// notified when the object changes.
  bool removeListener(VoidCallback listener) {
    final remove = _implChangeNotifier != null;
    if (remove) {
      _implChangeNotifier?.removeListener(listener);
    }
    return remove;
  }
}

/// Implementing ChangeNotifier
class ImplNotifyListenersChangeNotifier with ChangeNotifier {
  /// Whether any listeners are currently registered.
  bool get hasChangeListeners =&amp;gt; super.hasListeners;

  /// Call all the registered listeners.
  @override
  // ignore: unnecessary_overrides
  void notifyListeners() =&amp;gt; super.notifyListeners();

// The 'unnecessary overrides' prevent the Dart Analysis warning:
// The member 'hasListeners' can only be used within instance members of
// subclasses of 'package: change_notifier.dart'.
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The trick is when you attach this Mixin, it supplies a ChangeNotifier as field property instead (see first screenshot below). In the second screenshot, a ChangeNotifier is instead attached to a very simple class. It is that class that is then instantiated as a field property in the method, &lt;strong&gt;initChangeNotifier&lt;/strong&gt;()(see first screenshot below).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwbr59lvvomowehnq4az6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwbr59lvvomowehnq4az6.png" width="800" height="694"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/cb5b04f7a1d63c020c923cdd1f4be31df6bb3b42/lib/part14_change_notifier_class.dart#L16" rel="noopener noreferrer"&gt;part14_change_notifier_class.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fml7a4q4nnezz5412l0b4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fml7a4q4nnezz5412l0b4.png" width="800" height="700"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/cb5b04f7a1d63c020c923cdd1f4be31df6bb3b42/lib/part14_change_notifier_class.dart#L76" rel="noopener noreferrer"&gt;part14_change_notifier_class.dart&lt;/a&gt;



&lt;p&gt;A closer look at the Mixin below, reveals how the traditional methods found in the ChangeNotifier are then mirrored in this Mixin. You can see in the third screenshot below, the methods &lt;strong&gt;notifyListeners&lt;/strong&gt;(), &lt;strong&gt;addListener&lt;/strong&gt;(),and &lt;strong&gt;removeListener&lt;/strong&gt;() are all called by functions of the same name.&lt;/p&gt;

&lt;p&gt;Further note, the ChangeNotifier field property is nullable. A Mixin can’t have a constructor, and so it’s up to the user to properly use the Mixin and to call both the method, &lt;strong&gt;initChangeNotifier&lt;/strong&gt;(), and the method, &lt;strong&gt;disposeChangeNotifier&lt;/strong&gt;(), when appropriate. If not done so, the Mixin will not crash, but instead just not work properly. It’s on you to work it properly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwbr59lvvomowehnq4az6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwbr59lvvomowehnq4az6.png" width="800" height="694"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/cb5b04f7a1d63c020c923cdd1f4be31df6bb3b42/lib/part14_change_notifier_class.dart#L16" rel="noopener noreferrer"&gt;part14_change_notifier_class.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fka2vsyrt7o5glo50z622.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fka2vsyrt7o5glo50z622.png" width="800" height="687"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/cb5b04f7a1d63c020c923cdd1f4be31df6bb3b42/lib/part14_change_notifier_class.dart#L38" rel="noopener noreferrer"&gt;part14_change_notifier_class.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flklz5x6xsktin783s68d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flklz5x6xsktin783s68d.png" width="800" height="695"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/cb5b04f7a1d63c020c923cdd1f4be31df6bb3b42/lib/part14_change_notifier_class.dart#L58" rel="noopener noreferrer"&gt;part14_change_notifier_class.dart&lt;/a&gt;



&lt;h2&gt;
  
  
  Add Some Class
&lt;/h2&gt;

&lt;p&gt;Note, what you could do is specially assign such a Mixin to a State class, but it wouldn’t be very practical. You would have to dedicate a new Mixin to each State class. That’s because you would have use the &lt;strong&gt;on&lt;/strong&gt; clause (see the first screenshot below) to reference that specific State class. However, you can then include a &lt;strong&gt;dispose&lt;/strong&gt;() method in the Mixin. It would be called by the State object. See how that works?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5oew5iorfa6ac8evlj86.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5oew5iorfa6ac8evlj86.png" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://gist.github.com/Andrious/6522e850f1cab79bb33dd70c0b345782#file-impl_change_notifier_mixin-dart-L16" rel="noopener noreferrer"&gt;impl_change_notifier_mixin.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fergu1rvuaa5vl0tgkz0q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fergu1rvuaa5vl0tgkz0q.png" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://gist.github.com/Andrious/da73c21c2edff5fdf8ef0bb3bf75c321#file-counter_listenable-dart-L51" rel="noopener noreferrer"&gt;counter_listenable.dart&lt;/a&gt;



&lt;p&gt;&lt;code&gt;class _MyHomePageState extends State&amp;lt;MyHomePage&amp;gt; with ImplNotifyListenersChangeNotifierMixin;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The second screenshot above is a simple counter app utilizing this particular Mixin. With every push of the button, you then use the functions &lt;strong&gt;setBuilder&lt;/strong&gt;() and &lt;strong&gt;notifyListeners&lt;/strong&gt;() to only rebuild the &lt;em&gt;Text&lt;/em&gt; widget containing the count. The rest of the screen is left untouched.&lt;/p&gt;

&lt;p&gt;That’s the primary purpose of the &lt;strong&gt;setBuilder&lt;/strong&gt;() function found in the Mixin. It returns a Widget defined by its supplied builder, and that Widget is only rebuilt with the function call, &lt;strong&gt;notifyListeners&lt;/strong&gt;(). Your interface could be dotted with these &lt;strong&gt;setBuilder&lt;/strong&gt;() functions. For better performance, only those areas of the screen are rebuilt instead of the whole screen.&lt;/p&gt;

&lt;p&gt;The class, &lt;a href="https://github.com/AndriousSolutions/state_extended/blob/cb5b04f7a1d63c020c923cdd1f4be31df6bb3b42/lib/part13_statex_controller.dart#L15" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;, in the example app, &lt;a href="https://github.com/Andrious/flutter_weather/tree/70d527018bc08eb4b4139408dc8c34d5f19aee68" rel="noopener noreferrer"&gt;flutter_weather&lt;/a&gt;, has its own &lt;strong&gt;dispose&lt;/strong&gt;() function. Therefore, in the first screenshot below, you can see the Mixin is attached to this class, and the method, &lt;strong&gt;disposeChangeNotifier&lt;/strong&gt;(),is called in its &lt;strong&gt;dispose&lt;/strong&gt;() method. In the second screenshot, you see the function, &lt;strong&gt;setBuilder&lt;/strong&gt;(), is called.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw89fcyzjy25lrxqse05j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw89fcyzjy25lrxqse05j.png" width="800" height="695"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/cb5b04f7a1d63c020c923cdd1f4be31df6bb3b42/lib/part13_statex_controller.dart#L15" rel="noopener noreferrer"&gt;part13_statex_controller.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjre054hph8y9nbui69sd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjre054hph8y9nbui69sd.png" width="800" height="699"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/flutter_weather/blob/70d527018bc08eb4b4139408dc8c34d5f19aee68/lib/main/view/settings/settings_page.dart#L36" rel="noopener noreferrer"&gt;settings_page.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frh7r3h1vxby79t5g4442.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frh7r3h1vxby79t5g4442.gif" width="740" height="1558"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the video above, you see this simple app allows you can tap to another screen and switch the city of Chicago’s temperature from Celsius to Fahrenheit (°C to °F). Again, the second screenshot above shows how this second screen is implemented. When the user taps on the Switch widget to change from Celsius to Fahrenheit, the class, &lt;em&gt;StateXController&lt;/em&gt;, calls the function, notifyListeners(). That will call the Widget builder in the &lt;strong&gt;setBuilder&lt;/strong&gt;() function again rebuilding the Switch widget with now the toggled &lt;em&gt;isCelsius&lt;/em&gt; value. Easy peasy.&lt;/p&gt;

&lt;p&gt;Lastly, let’s examine the &lt;strong&gt;setBuilder&lt;/strong&gt;() function in the first screenshot below. It utilizes the StatefulWidget, [&lt;a href="https://gist.github.com/Andrious/fbe53696ff3c4f7d37c61b9a4472d35d#file-listenable_widget_builder-dart-L9" rel="noopener noreferrer"&gt;ListenableWidgetBuilder&lt;/a&gt;]. You’ll have to get a copy of this StatefulWidget as well to use the Mixin. This StatefulWidget takes in the ChangeNotifier as a [&lt;a href="https://github.com/flutter/flutter/blob/455be19d928fa8e0e5bb26904f2d0f57312794c6/packages/flutter/lib/src/foundation/change_notifier.dart#L61" rel="noopener noreferrer"&gt;Listenable&lt;/a&gt;] and its State object, &lt;em&gt;_ListenableState&lt;/em&gt;, adds the function, &lt;strong&gt;_callBuild()&lt;/strong&gt;, as a listener (see the second screenshot below). In the third screenshot below, you can see the function, &lt;strong&gt;_callBuild()&lt;/strong&gt;, merely calls the &lt;strong&gt;build&lt;/strong&gt;() function listed further below. See how that works?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fka2vsyrt7o5glo50z622.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fka2vsyrt7o5glo50z622.png" width="800" height="687"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/cb5b04f7a1d63c020c923cdd1f4be31df6bb3b42/lib/part14_change_notifier_class.dart#L38" rel="noopener noreferrer"&gt;part14_change_notifier_class.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1fa9bfm5j4ibqhkxmxls.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1fa9bfm5j4ibqhkxmxls.png" width="800" height="688"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/cb5b04f7a1d63c020c923cdd1f4be31df6bb3b42/lib/part15_listenable_widget_builder.dart#L38" rel="noopener noreferrer"&gt;part15_listenable_widget_builder.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F12r34btwhihtoo71jigg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F12r34btwhihtoo71jigg.png" width="800" height="690"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/cb5b04f7a1d63c020c923cdd1f4be31df6bb3b42/lib/part15_listenable_widget_builder.dart#L74" rel="noopener noreferrer"&gt;part15_listenable_widget_builder.dart&lt;/a&gt;



&lt;p&gt;I hope this has given you some insight about the ChangeNotifier.&lt;/p&gt;

&lt;p&gt;Cheers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/andrious"&gt;→ Other Stories by Greg Perry&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>programming</category>
    </item>
    <item>
      <title>Little More Efficient</title>
      <dc:creator>Greg Perry</dc:creator>
      <pubDate>Fri, 25 Oct 2024 16:08:55 +0000</pubDate>
      <link>https://dev.to/andrious/little-more-efficient-5a71</link>
      <guid>https://dev.to/andrious/little-more-efficient-5a71</guid>
      <description>&lt;p&gt;&lt;em&gt;A Little More Framework for the Flutter Framework makes for better apps&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Part of the &lt;a href="https://andrious.medium.com/the-little-more-series-94b0a9c6cd25" rel="noopener noreferrer"&gt;‘Little More’ Series&lt;/a&gt;, this article will highlight the ability of updating only those parts of your app’s interface that have changed. Flutter’s  InheritedWidget provides the means, but many apps continue to have their whole interface rebuilt. This only degrades performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Depend On It
&lt;/h2&gt;

&lt;p&gt;Using Flutter, for example, you can have three widgets each displaying an image of a animal. Each widget ‘depends’ on the same InheritedWidget. In Flutter, if that InheritedWidget is called again, all three of those animal widgets are rebuilt and will display a new image. Only those areas of the screen are updated. Tap on the video below and see for yourself.&lt;/p&gt;

&lt;p&gt;The first screenshot below displays the example app, &lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example" rel="noopener noreferrer"&gt;builtin_inherittedwidget_example&lt;/a&gt;. It’s a StateX object (see &lt;a href="https://pub.dev/packages/state_extended" rel="noopener noreferrer"&gt;state_extended package&lt;/a&gt;) assigned as a ‘dependency’ to a particular InheritedWidget using the function, &lt;strong&gt;dependOnInheritedWidget&lt;/strong&gt;(). The second screenshot below is the code for the footer buttons that are pressed one after the other in the accompanying video. Each ‘onPressed’ function is also highlighted with a red arrow.&lt;/p&gt;

&lt;p&gt;Note, how the arrows highlight the separation of responsibilities in the code. The variables ‘_con’ and ‘con’ in each screenshot performs the ‘event-handling’ and ‘logic’ involved in the code. The rest of the code is only concerned with the interface (see &lt;a href="https://andrious.medium.com/little-more-control-fc4467114eb8" rel="noopener noreferrer"&gt;Little More Control&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2fp8h26yijpgxm2zhday.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2fp8h26yijpgxm2zhday.png" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/319c67ac9dfa139f4215fcf751978952ad857813/lib/main/home/gridview/view/image_api.dart#L34" rel="noopener noreferrer"&gt;image_api.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F41erjekfgmhoxhqn8dva.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F41erjekfgmhoxhqn8dva.png" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/319c67ac9dfa139f4215fcf751978952ad857813/lib/main/home/view/home_page.dart#L53" rel="noopener noreferrer"&gt;home_page.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F550%2F1%2A7S4cVPdpkka6T1BMMQA9xw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F550%2F1%2A7S4cVPdpkka6T1BMMQA9xw.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example app, four StateX objects have the named parameter, &lt;em&gt;useInherited&lt;/em&gt;, set to true (see screenshots below). That means each will use their built-in InheritedWidget. Each represents a particular animal, and each will manipulate three additional StateX objects that display an image of that animal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F88m1btzzwwecg9lr7iy2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F88m1btzzwwecg9lr7iy2.png" width="800" height="342"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/3625328e8d5afb1e6d7cd211fb930e4fdcb29bc5/lib/main/home/inherited/view/inherit_bird.dart#L13" rel="noopener noreferrer"&gt;inherit_bird.dart&lt;/a&gt;  and  &lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/3625328e8d5afb1e6d7cd211fb930e4fdcb29bc5/lib/main/home/inherited/view/inherit_cat.dart#L12" rel="noopener noreferrer"&gt;inherit_cat.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcyjmn1hppy6tolmf9j6r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcyjmn1hppy6tolmf9j6r.png" width="800" height="345"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/3625328e8d5afb1e6d7cd211fb930e4fdcb29bc5/lib/main/home/inherited/view/inherit_dog.dart#L12" rel="noopener noreferrer"&gt;inherit_dog.dart&lt;/a&gt;  and  &lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/3625328e8d5afb1e6d7cd211fb930e4fdcb29bc5/lib/main/home/inherited/view/inherit_fox.dart#L12" rel="noopener noreferrer"&gt;inherit_fox.dart&lt;/a&gt;



&lt;p&gt;The first screenshot below displays the built-in InheritedWidget. It’s called, StateXInheritedWidget. Any ‘dependent’ Widgets will be rebuilt when that InheritedWidget is called again. In Flutter, when you call an InheritedWidget again, its corresponding InheritedElement object will eventually call the function, &lt;strong&gt;notifyClients&lt;/strong&gt;(). See the second screenshot below. There, the InheritedWidget’s dependencies are notified in turn, and they are rebuilt.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5vuz7py8xljg4z3vu0ou.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5vuz7py8xljg4z3vu0ou.png" width="800" height="693"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/e1aa805355f6c58a693766961a0eceebd204e228/lib/part06_inherited_widget_state_mixin.dart#L20" rel="noopener noreferrer"&gt;part06_inherited_widget_state_mixin.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9wpsczmyk5mx38mfgw0q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9wpsczmyk5mx38mfgw0q.png" width="800" height="641"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/flutter/flutter/blob/a775f8a0b8326b6b407d086bad61c550ab77bbc2/packages/flutter/lib/src/widgets/framework.dart#L6221" rel="noopener noreferrer"&gt;framework.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9r4kvk8iv5hepzyjbj31.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9r4kvk8iv5hepzyjbj31.png" width="800" height="693"&gt;&lt;/a&gt;&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/e1aa805355f6c58a693766961a0eceebd204e228/lib/part06_inherited_widget_state_mixin.dart#L20" rel="noopener noreferrer"&gt;06_inherited_widget_state_mixin.dart&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note, if the property, useInherited, is set to false, the &lt;strong&gt;builder&lt;/strong&gt;() function is instead called with every rebuild (the third screenshot above). Things work like Flutter’s original State class calling the &lt;strong&gt;build&lt;/strong&gt;() function. The resulting child widget is returned completely foregoing the built-in InheritedWidget.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make A Splash
&lt;/h2&gt;

&lt;p&gt;As an aside, I thought I’d introduce a simple little splash screen, a little kitten, to the example app. See the video below. Using Fluttery, you’re given three ways to introduce a Splash Screen. See the second screenshot below. The first parameter, &lt;em&gt;splashScreen&lt;/em&gt;, takes precedence, but instead of instantiating a widget right there in the initialization, you have the option to instantiate a widget either with the ‘on’ method or with the ‘inline’ method. Note, the ‘inline’ version takes last precedence.&lt;/p&gt;

&lt;p&gt;A Splash Screen in Fluttery remains displayed until all the start up operations are completed. The three ‘cat’ image widgets in the example app now also display the little kitten. Cute, no? It takes time to complete such a network call to download an image; best to have something ‘spinning’ while you wait.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F303qn2x9fql2szpqwygj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F303qn2x9fql2szpqwygj.png" width="800" height="496"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/319c67ac9dfa139f4215fcf751978952ad857813/lib/main.dart#L1" rel="noopener noreferrer"&gt;main.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr9m15g3g4jbykpghbtm7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr9m15g3g4jbykpghbtm7.png" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/319c67ac9dfa139f4215fcf751978952ad857813/lib/app/view/app_view.dart#L4" rel="noopener noreferrer"&gt;app_view.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimgur.com%2Fa%2F2rK1ebP" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimgur.com%2Fa%2F2rK1ebP" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Future Is Now
&lt;/h2&gt;

&lt;p&gt;Each StateX object in this example app has a built-in FutureBuilder as well. How many times have I seen apps instantiate Widgets and Classes even before the &lt;strong&gt;runApp&lt;/strong&gt;() function is called?! An example of this is displayed below. They’re instantiated and set up nowhere near where they’ll be used, but since there’s no logical place to perform such operations, the developer has no other choice! Not good.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmlurb52jwqmw3vowcs12.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmlurb52jwqmw3vowcs12.png" alt="Code before the runApp() function" width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You need a logical place so such tasks. They have to be completed before a particular screen is displayed, and in the StateX class, such a place is in the function, &lt;strong&gt;initAsync&lt;/strong&gt;().&lt;/p&gt;

&lt;p&gt;The first screenshot below is the example app’s first &lt;strong&gt;initAsync&lt;/strong&gt;() function. For demonstration purposes, the app is delayed ten seconds so you can appreciate how cute the little kitten is at startup. Again, this ‘logic’ is found in a Controller class and nowhere near the interface. Nice.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhldnbkfo86mbuxg3km3x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhldnbkfo86mbuxg3km3x.png" width="800" height="496"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/319c67ac9dfa139f4215fcf751978952ad857813/lib/app/controller/app_controller.dart#L97" rel="noopener noreferrer"&gt;app_controller.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flyiirzjtnuva6cr04do2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flyiirzjtnuva6cr04do2.png" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/319c67ac9dfa139f4215fcf751978952ad857813/lib/main/home/gridview/controller/image_api_controller.dart#L47" rel="noopener noreferrer"&gt;image_api_controller.dart&lt;/a&gt;



&lt;p&gt;The example app relies on four public API’s to retrieve images. The first screenshot below, for example, gives you the API used to retrieve bird images. They’re not the fastest Web services in the World. They are prone to lag and complete failure frankly, and so as you see in the second screenshot above, the process is pretty involving. However, it’s necessary, and so it too is tucked away in a &lt;strong&gt;initAsync&lt;/strong&gt;() function found in another Controller class, &lt;em&gt;ImageAPIController&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The ‘image’ Widget has the class type, &lt;em&gt;ImageAPIStateX&lt;/em&gt;, and it takes in this Controller (second screenshot below). The Controller, &lt;em&gt;ImageAPIController&lt;/em&gt;, performs the actual data retrieval (the image download) while the StatefuleWidget worries about how that data is displayed. Very nice.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq8j7xj4pq88p3j3arrer.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq8j7xj4pq88p3j3arrer.png" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/319c67ac9dfa139f4215fcf751978952ad857813/lib/main/home/gridview/images/view/network_bird.dart#L12" rel="noopener noreferrer"&gt;network_bird.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbdr972ymv02xfke0st9v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbdr972ymv02xfke0st9v.png" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/319c67ac9dfa139f4215fcf751978952ad857813/lib/main/home/gridview/view/image_api.dart#L10" rel="noopener noreferrer"&gt;image_api.dart&lt;/a&gt;



&lt;h2&gt;
  
  
  Controlling Events
&lt;/h2&gt;

&lt;p&gt;Again, the four animal-type InheritedWidgets are inserted into the Widget tree in the app’s home screen. See the first screenshot below. Each with a unique SOC (State Object Controller). For example, the InheritBird class has the controller, &lt;em&gt;BirdController&lt;/em&gt;. See the second screenshot below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhxoxrth4s5qb1j1vrfrc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhxoxrth4s5qb1j1vrfrc.png" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/e1aa805355f6c58a693766961a0eceebd204e228/lib/part06_inherited_widget_state_mixin.dart#L20" rel="noopener noreferrer"&gt;home_page.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgv93q1y7ztm8o2ra6j6w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgv93q1y7ztm8o2ra6j6w.png" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/3625328e8d5afb1e6d7cd211fb930e4fdcb29bc5/lib/main/home/inherited/view/inherit_bird.dart#L17" rel="noopener noreferrer"&gt;inherit_bird.dart&lt;/a&gt;



&lt;p&gt;Using Fluttery, each Controller object will have a reference to its assigned StateX object. Doing so provides the means to assign dependency as well as call the built-in InheritedWidget again. See the second screenshot below.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;firstState?.dependOnInheritedWidget(context);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;firstState?.notifyClients(context)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1931fuk61be39eonbzex.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1931fuk61be39eonbzex.png" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/319c67ac9dfa139f4215fcf751978952ad857813/lib/main/home/gridview/images/controller/bird_controller.dart#L4" rel="noopener noreferrer"&gt;bird_controller.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldd87xrqyi1htevkqwto.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldd87xrqyi1htevkqwto.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/319c67ac9dfa139f4215fcf751978952ad857813/lib/main/home/inherited/controller/inherit_controller.dart#L9" rel="noopener noreferrer"&gt;inherit_controller.dart&lt;/a&gt;



&lt;p&gt;That very same Controller is assigned to the corresponding ‘Image’ widget that displays an animal image. For example, in the first screenshot below, you see the class, &lt;em&gt;NetworkBird. *It displays a bird image — assigned the appropriate API information. The State class, *_NetworkBirdState&lt;/em&gt;, continues on the second screenshot where the Controller object, &lt;em&gt;BirdController&lt;/em&gt;, then registers this Widget (really it registers its StatefulElement object, context) as a dependency to the InheritedWidget in the State object, &lt;em&gt;InheritBird&lt;/em&gt;. Easy Peasy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdrsoe3cjstemnjgxjsx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdrsoe3cjstemnjgxjsx.png" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/319c67ac9dfa139f4215fcf751978952ad857813/lib/main/home/gridview/images/view/network_bird.dart#L12" rel="noopener noreferrer"&gt;network_bird.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2fp8h26yijpgxm2zhday.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2fp8h26yijpgxm2zhday.png" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/319c67ac9dfa139f4215fcf751978952ad857813/lib/main/home/gridview/view/image_api.dart#L33" rel="noopener noreferrer"&gt;image_api.dart&lt;/a&gt;



&lt;p&gt;See below, and you’ll find each type of animal has its own Controller:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F8452%2F1%2AaMada6IKcOMAM9kPLMcq-Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F8452%2F1%2AaMada6IKcOMAM9kPLMcq-Q.png" width="800" height="246"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/319c67ac9dfa139f4215fcf751978952ad857813/lib/main/home/gridview/images/controller/bird_controller.dart#L4" rel="noopener noreferrer"&gt;bird_controller.dart&lt;/a&gt;  and  &lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/319c67ac9dfa139f4215fcf751978952ad857813/lib/main/home/gridview/images/controller/cat_controller.dart#L4" rel="noopener noreferrer"&gt;cat_controller.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F8452%2F1%2AniQ7JjKbTzm9r9UX4qBZdg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F8452%2F1%2AniQ7JjKbTzm9r9UX4qBZdg.png" width="800" height="247"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/319c67ac9dfa139f4215fcf751978952ad857813/lib/main/home/gridview/images/controller/dog_controller.dart#L4" rel="noopener noreferrer"&gt;dog_controller.dart&lt;/a&gt;  and  &lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/319c67ac9dfa139f4215fcf751978952ad857813/lib/main/home/gridview/images/controller/fox_controller.dart#L4" rel="noopener noreferrer"&gt;fox_controller.dart&lt;/a&gt;



&lt;p&gt;Take the time to download the example app, and review the process yourself. Note, how the whole process is broken down into parts and delegated to separate classes. This promotes modular development and code reuse and consequently more efficient and more effective implementation and maintenance.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;I’ll continue with a deeper dive into the inner workings of Flutter‘s StatefulWidget, State class, Futurebuilder, and InheritedWidgets. Nothing new here. Merely implementing capabilities already found in Flutter as well as following some ‘good programming practices’ every developer should know.&lt;/p&gt;

&lt;h2&gt;
  
  
  Control Your Future
&lt;/h2&gt;

&lt;p&gt;Once the &lt;strong&gt;initAsync&lt;/strong&gt;() function is called and creates a Future for a StateX object, in most cases, you don’t want to create that Future again. These are synchronous operations that need to be completed once before the StateX object can display its interface. &lt;/p&gt;

&lt;p&gt;Such operations would include establishing connections to Web services and or the opening of databases. Opening such connections again and again with every interface change would be grossly inefficient. Unless, of course, you’re calling an particular public API to retrieve a new animal image.&lt;/p&gt;

&lt;p&gt;In the first screenshot below, you can see the StateX’s &lt;strong&gt;runInitAsync&lt;/strong&gt;() function is used to determine if its corresponding &lt;strong&gt;initAsync&lt;/strong&gt;() function is to be called again or not. The &lt;strong&gt;runInitAsync&lt;/strong&gt;() function is implemented in the second screenshot below and only returns false when appropriate.&lt;/p&gt;

&lt;p&gt;I’ve placed a menu option in this example app to demonstrate how the images would simply not change at all if the &lt;strong&gt;runInitAsync&lt;/strong&gt;() functions involved always returned false. Please, examine the video.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftr8ydz84i2ajyo5s2okc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftr8ydz84i2ajyo5s2okc.png" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/e1aa805355f6c58a693766961a0eceebd204e228/lib/part05_futurebuilder_state_mixin.dart#L12C1-L12C21" rel="noopener noreferrer"&gt;part05_futurebuilder_state_mixin.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fybw06uruhxj3m6heycs7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fybw06uruhxj3m6heycs7.png" width="800" height="691"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/3625328e8d5afb1e6d7cd211fb930e4fdcb29bc5/lib/main/home/gridview/view/image_api.dart#L45" rel="noopener noreferrer"&gt;image_api.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AhtBO2RguFaXW0WarA2Xw_Q.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AhtBO2RguFaXW0WarA2Xw_Q.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Going To Dark Side
&lt;/h2&gt;

&lt;p&gt;Again, there are situations where the &lt;strong&gt;runInitAsync&lt;/strong&gt;() function should return false. Rebuilding the app’s whole interface to convey it in dark mode would be one of them. In the screenshot below, when the &lt;strong&gt;darkMode&lt;/strong&gt;() function is called from the app’s menu, not only is the app’s theme toggled (the whole interface rebuilt with the call,App.setState()), but a particular property created for the example app is set to false:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;runInitAsync = false;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That property you’ve already seen in the implemented &lt;strong&gt;runInitAsync&lt;/strong&gt;() function displayed above. The first video below runs things properly, but the second video demonstrates what happens if you don’t ever return false in the &lt;strong&gt;runAsync&lt;/strong&gt;() function. Again in most cases, you don’t want to create the Future again (the database is already open). However, if you always return true in the example app, you’ll inappropriately lose your animal images when changing back to dark mode.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;return appController.runFuture &amp;amp;&amp;amp; appController.runInitAsync&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F27igymrf3eobldn47zxu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F27igymrf3eobldn47zxu.png" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/3625328e8d5afb1e6d7cd211fb930e4fdcb29bc5/lib/app/controller/app_controller.dart#L59" rel="noopener noreferrer"&gt;app_controller.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AZWdYc35xlwFJsSjWiKeI8A.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AZWdYc35xlwFJsSjWiKeI8A.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A1EU-chhW2VU5aV_Be0zerQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A1EU-chhW2VU5aV_Be0zerQ.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s continue down the example app’s popup menu and see how one can now interfere with those built-in InheritedWidgets.&lt;/p&gt;

&lt;h2&gt;
  
  
  There’s No Inheritance
&lt;/h2&gt;

&lt;p&gt;Deselect the menu option, Use InheritedWidget, and you’ll have a rather boring example app on your hands. Remember, it’s the four StateX objects listed below that represent the four types of animals displayed. They use their built-in InheritedWidget to take in three additional widgets as ‘dependencies’ to then display those animals in a grid.&lt;/p&gt;

&lt;p&gt;In the video below, you can see when the ‘New Cats’ button is pressed, three new cat images appear (the API is providing duplicate images, but you know what I mean). As the video continues, you can see the app is no longer working. The menu option, Use InheritedWidget,is deselected — the named parameter, useInherited, is therefore set to false.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyfxs2plrh0xqrhlic9bo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyfxs2plrh0xqrhlic9bo.png" width="800" height="342"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/3625328e8d5afb1e6d7cd211fb930e4fdcb29bc5/lib/main/home/inherited/view/inherit_bird.dart#L13" rel="noopener noreferrer"&gt;inherit_bird.dart&lt;/a&gt;  and  &lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/3625328e8d5afb1e6d7cd211fb930e4fdcb29bc5/lib/main/home/inherited/view/inherit_cat.dart#L12" rel="noopener noreferrer"&gt;inherit_cat.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv8kgt19vcix2mig5p23i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv8kgt19vcix2mig5p23i.png" width="800" height="345"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/3625328e8d5afb1e6d7cd211fb930e4fdcb29bc5/lib/main/home/inherited/view/inherit_dog.dart#L12" rel="noopener noreferrer"&gt;inherit_dog.dart&lt;/a&gt;  and  &lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/3625328e8d5afb1e6d7cd211fb930e4fdcb29bc5/lib/main/home/inherited/view/inherit_fox.dart#L12" rel="noopener noreferrer"&gt;inherit_fox.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A_b51VBlx6WUJTpVKuQy8ag.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A_b51VBlx6WUJTpVKuQy8ag.gif" width="1024" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note, you can still just tap on individual images and a new image appears. That’s because that’s a separate process. The &lt;strong&gt;onTap&lt;/strong&gt;() method merely calls the &lt;strong&gt;setState&lt;/strong&gt;() function of the associated State object. See the second screenshot below. In the video above, that would be the State class, &lt;em&gt;_NetworkCatState&lt;/em&gt;. The &lt;strong&gt;setState&lt;/strong&gt;() method is called, but not before its &lt;strong&gt;initAsync&lt;/strong&gt;() function will load a new image. That’s because the global flag, runInitAsync, was set to true (the first screenshot below). See how this works?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5fdlwaf34qz9lrjxt2ai.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5fdlwaf34qz9lrjxt2ai.png" width="800" height="691"&gt;&lt;/a&gt;&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/3625328e8d5afb1e6d7cd211fb930e4fdcb29bc5/lib/main/home/gridview/view/image_api.dart#L45" rel="noopener noreferrer"&gt;image_api.dart&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flxwt5ngn5bn4fr0aaqls.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flxwt5ngn5bn4fr0aaqls.png" width="800" height="693"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/3625328e8d5afb1e6d7cd211fb930e4fdcb29bc5/lib/main/home/gridview/controller/image_api_controller.dart#L18" rel="noopener noreferrer"&gt;image_api_controller.dart&lt;/a&gt;



&lt;h2&gt;
  
  
  Going Home
&lt;/h2&gt;

&lt;p&gt;You may have noticed with every menu option selection, the whole screen gets refreshed with a grid display of new animal images. It’s a necessary step in Flutter as that portion of the widget tree is being rebuilt. The app’s home page is a StatefulWidget called, HomePage, and the &lt;strong&gt;build&lt;/strong&gt;() function for its State object gets called with the first two menu option selections.&lt;/p&gt;

&lt;p&gt;As you see in the second screenshot below, it’s the controller called,HomeController,that calls that &lt;strong&gt;build&lt;/strong&gt;() function. It’s the controller assigned to the State class,_HomePageState(first screenshot below). Note, State Object Controllers tend to utilize a factory constructor allowing for commands like the one listed below. You’re not instantiating a new instance of the class but working instead with the original instance:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;HomeController().setState((){});&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa41uo80qdy9rxq9uikuu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa41uo80qdy9rxq9uikuu.png" width="800" height="699"&gt;&lt;/a&gt;&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/3625328e8d5afb1e6d7cd211fb930e4fdcb29bc5/lib/main/home/view/home_page.dart#L12" rel="noopener noreferrer"&gt;home_page.dart&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl0zudmnfmn6qz2z2s1vt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl0zudmnfmn6qz2z2s1vt.png" width="800" height="692"&gt;&lt;/a&gt;&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/3625328e8d5afb1e6d7cd211fb930e4fdcb29bc5/lib/app/controller/app_controller.dart#L41" rel="noopener noreferrer"&gt;app_controller.dart&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AWggGMpyFmBvRjk1R2S5-aA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AWggGMpyFmBvRjk1R2S5-aA.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Turn To Black
&lt;/h2&gt;

&lt;p&gt;The menu option, Dark Mode, involves the Fluttery Framework’s &lt;em&gt;App&lt;/em&gt; object. With Fluttery, you can reassign your app’s overall color theme using the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;App.themeData = darkMode;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This command appears in the &lt;strong&gt;darkMode&lt;/strong&gt;() method (second screenshot below) and is called when you select the menu option, Dark Mode. See the first screenshot below. Using Fluttery, the whole interface is then rebuilt with the call,App.setState().Let’s see how that works next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ipeeh1bwv060nm40ap7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ipeeh1bwv060nm40ap7.png" width="800" height="736"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/3625328e8d5afb1e6d7cd211fb930e4fdcb29bc5/lib/app/view/menu/app_menu.dart#L62" rel="noopener noreferrer"&gt;app_menu.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7aj2muzfw1hz7nqh234x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7aj2muzfw1hz7nqh234x.png" width="800" height="695"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/3625328e8d5afb1e6d7cd211fb930e4fdcb29bc5/lib/app/controller/app_controller.dart#L59" rel="noopener noreferrer"&gt;app_controller.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzrtfow8dbtzle3ipjnfs.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzrtfow8dbtzle3ipjnfs.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have the video changing the app to dark mode listed below again. In the first screenshot below, the app’s first State object, AppState,takes in the StatefulWidget, HomePage,as the app’s home page. When the AppState’s &lt;strong&gt;build&lt;/strong&gt;() function is called again (second screenshot below), the MaterialApp widget that makes up this app (running in an Android emulator) is created again. This time, with a ‘dark mode’ theme. Yes, as the video would suggest, this all runs in a flash. Flutter’s widget tree is efficiently fast.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkp0hetst2boydsvaejh3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkp0hetst2boydsvaejh3.png" width="800" height="700"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/3625328e8d5afb1e6d7cd211fb930e4fdcb29bc5/lib/app/view/app_view.dart#L9" rel="noopener noreferrer"&gt;app_view.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F92icezpnxibb81o0wgoi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F92icezpnxibb81o0wgoi.png" width="800" height="699"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/fluttery_framework/blob/master/lib/view/app_state.dart#L564" rel="noopener noreferrer"&gt;app_state.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzrtfow8dbtzle3ipjnfs.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzrtfow8dbtzle3ipjnfs.gif" width="1024" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Recreate State
&lt;/h2&gt;

&lt;p&gt;Lastly, you must be aware that State objects, though recreated in ScrollViews and such lists, are only recreated in Flutter if its StatefulWidget counterpart is called with a ‘new’ key value.&lt;/p&gt;

&lt;p&gt;You can see, in the screenshots below, how I guarantee a State class is recreated with strategically placed &lt;strong&gt;UniqueKey&lt;/strong&gt;() functions. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F95zu93gfmsenk73bsbdb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F95zu93gfmsenk73bsbdb.png" width="800" height="693"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/fluttery_framework/blob/master/lib/view/app_statefulwidget.dart#L95" rel="noopener noreferrer"&gt;app_statefulwidget.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffdm3btlj0szvfm8f6nwj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffdm3btlj0szvfm8f6nwj.png" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/builtin_inherittedwidget_example/blob/3625328e8d5afb1e6d7cd211fb930e4fdcb29bc5/lib/main/home/view/home_page.dart#L34" rel="noopener noreferrer"&gt;home_page.dart&lt;/a&gt;



</description>
      <category>flutter</category>
      <category>programming</category>
    </item>
    <item>
      <title>Little More Control</title>
      <dc:creator>Greg Perry</dc:creator>
      <pubDate>Fri, 09 Aug 2024 19:48:13 +0000</pubDate>
      <link>https://dev.to/andrious/little-more-control-3o3b</link>
      <guid>https://dev.to/andrious/little-more-control-3o3b</guid>
      <description>&lt;p&gt;&lt;em&gt;A Little More Framework for the Flutter Framework makes for better apps&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Part of the &lt;a href="https://dev.to/andrious/the-little-more-series-19df"&gt;‘Little More’ Series&lt;/a&gt;, this article will review how introducing a Controller class to Futter’s State class not only encourages clean architecture but provides a State Management solution to your app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frw7d00yaifcltdj4ey6e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frw7d00yaifcltdj4ey6e.png" width="800" height="670"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://dev.to/andrious"&gt;Other Stories by Greg Perry&lt;/a&gt;



&lt;p&gt;A Google search of the Flutter website (&lt;a href="https://flutter.dev/" rel="noopener noreferrer"&gt;flutter.dev&lt;/a&gt;) highlights the many Widgets and other classes that include the named parameter, &lt;em&gt;controller&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.google.com/search?q=site%3Aflutter.dev+insubject%3A%22controller%22" rel="noopener noreferrer"&gt;site:flutter.dev insubject:"controller"&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In each case, a separate class object assists its host Widget by performing its designated tasks. Delegating work to a separate class mirrors the separation of responsibilities advocated by software design patterns. In this case, this usually involves the decoupling of the app’s interface (view) from its event handling, logic, and business rules (controller). Fluttery uses the [&lt;a href="https://pub.dev/packages/state_extended" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;] package because it allows State objects to have their own Controllers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6cg0axg6xe84m6sn925i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6cg0axg6xe84m6sn925i.png" alt="Design patterns often separate interface, logic and data" width="259" height="103"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Play Store app, [&lt;a href="https://play.google.com/store/apps/details?id=com.andrioussolutions.pexels_preview" rel="noopener noreferrer"&gt;Pexel Preview&lt;/a&gt;], uses the Fluttery Framework. Below is a screenshot of that app’s &lt;a href="https://pub.dev/documentation/state_extended/latest/topics/AppStateX%20class-topic.html" rel="noopener noreferrer"&gt;AppState&lt;/a&gt; object that defines its general look and behavior(see &lt;a href="https://dev.to/andrious/little-more-adaptive-5c3k"&gt;Little More Adaptive&lt;/a&gt;). Highlighted with arrows are the Controllers assigned to perform particular tasks. Again, a State object’s Controllers tend to work the logic while the State object itself with its &lt;strong&gt;build&lt;/strong&gt;() function is more concerned with the interface — a separation of responsibilities is made readily apparent.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7cpss8ylr7sz1qvvvih7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7cpss8ylr7sz1qvvvih7.png" width="800" height="496"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/pexels_preview/blob/3711434b0a93b0a9bb5f3a6376601630371e704c/lib/app/view/app_view.dart#L18" rel="noopener noreferrer"&gt;app_view.dart&lt;/a&gt;



&lt;h2&gt;
  
  
  Delegate, Delegate, Delegate
&lt;/h2&gt;

&lt;p&gt;In the first screenshot below, the tabs displayed in an example app’s main screen are highlighted with arrows. Each is conceived by the class, &lt;em&gt;GridViewScreen.&lt;/em&gt; In the second screenshot below, each is assigned a different Controller object. At a glance, this tells you all three will have the same general appearance while those three different Controllers would suggest there will be three separate and distinct processes going on.&lt;/p&gt;

&lt;p&gt;In truth, the only difference between these three Controllers is the data source and the title. Not the best example, but it does demonstrate how a State Object Controller (SOC) allows for this separation of responsibility. Each Controller accesses a different data source (model). You can switch out the data source within the Controller class itself without changing one bit of code on the interface side. This arrangement encourages more modular code. It promotes high cohesion and low coupling — all good attributes to have in software.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn0f2fvuvr3dm40uityx1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn0f2fvuvr3dm40uityx1.png" width="550" height="1165"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftgu37zt8y7e30a5c5h9f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftgu37zt8y7e30a5c5h9f.png" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/pexels_preview/blob/3a84e0762db50a6d0b1b8871d77bb3503bd7c685/lib/app/view/menu/app_scaffold.dart#L48" rel="noopener noreferrer"&gt;app_scaffold.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdx24cnbtxmkp6n1irb25.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdx24cnbtxmkp6n1irb25.png" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/pexels_preview/blob/3a84e0762db50a6d0b1b8871d77bb3503bd7c685/lib/main/view/main_screen/category_screen/controller/categories_controller.dart#L9" rel="noopener noreferrer"&gt;categories_controller.dart&lt;/a&gt;



&lt;p&gt;Frankly, as seen in the last screenshot above, we can take it further and give no hint at all, on the interface side, what’s involved in those three tabs. Note, how the use of a Controller class also allows for a degree of abstraction. This makes for more adaptive and more robust software.&lt;/p&gt;

&lt;h2&gt;
  
  
  State Object Controller
&lt;/h2&gt;

&lt;p&gt;You create a SOC by extending the class, &lt;a href="https://pub.dev/documentation/state_extended/latest/topics/State%20Object%20Controller-topic.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt; (No relation to the &lt;a href="https://pub.dev/documentation/get/latest/get_state_manager_src_simple_get_controllers/GetxController-class.html" rel="noopener noreferrer"&gt;GetXController&lt;/a&gt; class). It’s made up of code to reference and work with any and all the State objects it’s assigned to during the app’s lifecycle.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6d9youthe979qm9o8idq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6d9youthe979qm9o8idq.png" width="800" height="496"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/pexels_preview/blob/3711434b0a93b0a9bb5f3a6376601630371e704c/lib/main/view/main_screen/category_screen/controller/categories_controller.dart#L9" rel="noopener noreferrer"&gt;categories_controller.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fodk4pb28mae08owlwh8n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fodk4pb28mae08owlwh8n.png" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/pexels_preview/blob/3711434b0a93b0a9bb5f3a6376601630371e704c/lib/main/view/main_screen/recent_pics_screen/controller/recent_pics_controller.dart#L9" rel="noopener noreferrer"&gt;recent_pics_controller.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foddnt25xh6mfrsk2hj28.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foddnt25xh6mfrsk2hj28.png" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/pexels_preview/blob/3711434b0a93b0a9bb5f3a6376601630371e704c/lib/main/view/main_screen/top_vids_screen/controller/top_vids_controller.dart#L9" rel="noopener noreferrer"&gt;top_vids_controller.dart&lt;/a&gt;



&lt;h2&gt;
  
  
  Control The Scope
&lt;/h2&gt;

&lt;p&gt;The Controller class is yours to implement in any fashion you require frankly. For example, taking advantage of object-oriented principals, one Controller class used in the [&lt;a href="https://play.google.com/store/apps/details?id=com.andrioussolutions.pexels_preview" rel="noopener noreferrer"&gt;Pexel Preview&lt;/a&gt;] app is actually made up of three other classes. Class hierarchies also tend to make for more adaptive and more scalable software.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy1bu9hvak5sldjny32mk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy1bu9hvak5sldjny32mk.png" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/pexels_preview/blob/3711434b0a93b0a9bb5f3a6376601630371e704c/lib/main/view/main_screen/image_screens/view/grid_view/gride_view_screen.dart#L92" rel="noopener noreferrer"&gt;grid_view_screen.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7shnmi1dtvfb1l6479b3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7shnmi1dtvfb1l6479b3.png" width="690" height="364"&gt;&lt;/a&gt;&lt;/p&gt;
class hierarchy



&lt;p&gt;Note, how the other areas of the app (its interface and its data) have no idea this hierarchy exists—another characteristic of a clean architecture.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2ArLcSbwRbSjksJRCTL-2XFg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2ArLcSbwRbSjksJRCTL-2XFg.png" width="431" height="49"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Control The State
&lt;/h2&gt;

&lt;p&gt;Because a ‘Controller’ class is introduced to the State class, Fluttery has introduced a particular architecture — one that assigns distinct ‘roles’ to State objects and their Controllers. In particular, this arrangement allows you to rebuild your app’s interface from outside the Widget tree at any time and from anywhere — a core feature achieved by all State Management solutions.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h1&gt;
  
  
  Call setState() outside the State class anytime, anywhere
&lt;/h1&gt;
&lt;/blockquote&gt;

&lt;p&gt;The term, &lt;em&gt;State Management&lt;/em&gt;, originated from Web developers working with the ‘stateless’ environment that is the HTTP protocol — HTML pages famously did not retain state. State Management came about with the use of Sessions, Client-side cookies, etc. Since Flutter already retains state right out of the box, I would suggest Google took liberties and chose the term to advertise Flutter to the large Web development community.&lt;/p&gt;

&lt;p&gt;I'd prefer they didn't use the term, but they are a for-profit company after all. They want everyone to use Flutter. For Flutter, State Management best refers to the faithful rebuild of the current interface if and when the information displayed in that interface has changed:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3300%2F1%2As0FI4mYr_cTTghop8n47uQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3300%2F1%2As0FI4mYr_cTTghop8n47uQ.png" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://www.youtube.com/watch?v=UDWFxhobzhA&amp;amp;t=2694s" rel="noopener noreferrer"&gt;Which State Management&lt;/a&gt;



&lt;p&gt;Again, the current pile of ‘State Management solutions’ keeps track of the current interface displayed and will rebuild it when appropriate to convey changes. The screenshots below showcase how a State object keeps track of its controllers, and how the controllers themselves can update the interface at any time and from anywhere.&lt;/p&gt;

&lt;p&gt;The third screenshot is of Page 2’s controller class, and you can see there are many ways to update that interface. You always have reliable access to a particular State object to rebuild that portion of the screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4178%2F1%2AgPAJC9BqauESPmohjXDcGQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4178%2F1%2AgPAJC9BqauESPmohjXDcGQ.png" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/6d562a3fb059d372da22566b2c96c30b4ccfdca5/example/lib/src/view/home/page_01.dart#L19" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4188%2F1%2AQ3HyJQlrXrG6HULO8zWDqA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4188%2F1%2AQ3HyJQlrXrG6HULO8zWDqA.png" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/6d562a3fb059d372da22566b2c96c30b4ccfdca5/example/lib/src/view/home/page_01.dart#L46" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4172%2F1%2AubG1XVDcilWcAwUPK5kgew.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4172%2F1%2AubG1XVDcilWcAwUPK5kgew.png" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/6d562a3fb059d372da22566b2c96c30b4ccfdca5/example/lib/src/controller/home/controller.dart#L41" rel="noopener noreferrer"&gt;controller.dart&lt;/a&gt;



&lt;p&gt;Again, a Controller class is not new to Flutter. The code in the State class involves the interface while the code in the State Object Controller class involves everything else — a proven efficiency yet ‘keeping it Flutter.’&lt;/p&gt;

&lt;p&gt;Cheers.&lt;/p&gt;

&lt;p&gt;→ &lt;a href="https://andrious.medium.com/the-little-more-series-94b0a9c6cd25" rel="noopener noreferrer"&gt;The ‘Little More’ Series&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/andrious"&gt;→ Other Stories by Greg Perry&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>programm</category>
    </item>
    <item>
      <title>Little More Error Handling</title>
      <dc:creator>Greg Perry</dc:creator>
      <pubDate>Fri, 02 Aug 2024 15:44:22 +0000</pubDate>
      <link>https://dev.to/andrious/little-more-error-handling-i36</link>
      <guid>https://dev.to/andrious/little-more-error-handling-i36</guid>
      <description>&lt;p&gt;&lt;em&gt;A Little More Framework for the Flutter Framework makes for better apps&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Part of the &lt;a href="https://dev.to/andrious/the-little-more-series-19df"&gt;‘Little More’ Series&lt;/a&gt;, this article will detail the Error Handling available to you when using the Fluttery Framework.&lt;/p&gt;

&lt;p&gt;Handle your errors. True, you’re the greatest programmer that ever lived, and your code will never crash. However, I’m seeing code out there that assumes everything will run as expected, and we know that’s not good. Your code must anticipate the unexpected. It must! Here’s how.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F1%2AMfXvWeaIMUuoF5bosYX6aA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F1%2AMfXvWeaIMUuoF5bosYX6aA.png" alt="[Other Stories by Greg Perry](https://dev.to/andrious)" width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://dev.to/andrious"&gt;Other Stories by Greg Perry&lt;/a&gt;



&lt;p&gt;In the first screenshot below, we see a Fluttery Framework example app starting up. Note, that’s not your traditional &lt;strong&gt;runApp&lt;/strong&gt;() function. The original &lt;strong&gt;runApp&lt;/strong&gt;() function is called, but not before establishing some error handling first (see second screenshot below).&lt;/p&gt;

&lt;p&gt;Even before that, when using Fluttery, if the Widget instantiated and passed to that &lt;strong&gt;runApp&lt;/strong&gt;() function extends the class, &lt;em&gt;AppStatefulWidget&lt;/em&gt;, it creates the AppErrorHandler class object already right in its constructor (see third screenshot). And so, right from the start, your app has an Error Handler ready to go! Tap the screenshot’s captions to view the code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuoauylkwie79hfp8zzc8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuoauylkwie79hfp8zzc8.png" width="800" height="496"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/fluttery_framework/blob/94e8337dc6fd35f5c27e033ca6db8bec4e133239/example/lib/main.dart#L1" rel="noopener noreferrer"&gt;main.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F24hd4rdgby4odymty11b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F24hd4rdgby4odymty11b.png" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/fluttery_framework/blob/94e8337dc6fd35f5c27e033ca6db8bec4e133239/lib/src/view/platforms/run_app.dart#L17" rel="noopener noreferrer"&gt;run_app.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcwio35j8f0y2fm3ralc2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcwio35j8f0y2fm3ralc2.png" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/fluttery_framework/blob/94e8337dc6fd35f5c27e033ca6db8bec4e133239/lib/view/app_statefulwidget.dart#L35" rel="noopener noreferrer"&gt;app_statefulwidget.dart&lt;/a&gt;



&lt;p&gt;If you like, you’re then free to call the App’s Error Handler yet again (see below) and establish any third-party error handler (&lt;a href="https://firebase.google.com/docs/crashlytics" rel="noopener noreferrer"&gt;Firebase Crashlytics&lt;/a&gt;, &lt;a href="https://pub.dev/packages/catcher_2" rel="noopener noreferrer"&gt;Catcher 2&lt;/a&gt;, etc.). They will then catch errors for you in the fashion that they do.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1at7fsz82o217s9np3gc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1at7fsz82o217s9np3gc.png" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/workingmemory/blob/a8262ff0ea3389bdbbc52ced0c5b903b8cf68788/lib/src/app/controller/working_memory_app.dart#L147" rel="noopener noreferrer"&gt;working_memory_app.dart&lt;/a&gt;



&lt;h2&gt;
  
  
  The State of Error
&lt;/h2&gt;

&lt;p&gt;In the video below, there’s an exception thrown with every tap of the button, but you’d never know it. The exception is recognized right there in the State class resulting in the counter incrementing correctly.&lt;/p&gt;

&lt;p&gt;In Fluttery, every State object can perform its own error handling. Imagine a particular error is thrown in your app from time to time. A network drop for example. Whatever it may be, your app encounters an error in certain circumstances, but you’re ready for it. Your State object has a built-in error handler:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;void onError(FlutterErrorDetails details) {&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The video depicts the Fluttery Framework’s own example app. You can see in the first screenshot below, a &lt;strong&gt;FloatingActionButton&lt;/strong&gt; widget (if not testing the app) will explicitly throw an Exception. The second screenshot is of the residing State object. Its Error handler calls the &lt;strong&gt;onPress&lt;/strong&gt;() function in response to this particular error and successfully increments the counter. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2ARgCXVTWyRVcE6MilVVFGWg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2ARgCXVTWyRVcE6MilVVFGWg.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwj3w7qngx6b0z839mse2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwj3w7qngx6b0z839mse2.png" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/fluttery_framework/blob/master/example/lib/src/main/view/screens/app_counter.dart#L115" rel="noopener noreferrer"&gt;app_counter.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2cp5rre9aerxyl3vuk5r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2cp5rre9aerxyl3vuk5r.png" width="800" height="496"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/fluttery_framework/blob/master/example/lib/src/main/view/screens/app_counter.dart#L232" rel="noopener noreferrer"&gt;app_counter.dart&lt;/a&gt;



&lt;p&gt;It’s a very simple example, but it does demonstrate the potential here to modularize the error handling in your app. Isolating parts of your code more susceptible to error simply makes for a more reliable and more robust app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pass It On
&lt;/h2&gt;

&lt;p&gt;The error now continues up the Widget tree. It may be handled by the State object, but every error is an ‘app error’ and will be logged by the App’s State object in its own &lt;strong&gt;onError&lt;/strong&gt;() function. For example, the error introduced above is running from a phone emulator. Hence, the error is eventually reported in the IDE’s console screen. See below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05bnoqkvtf786l2bcav0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05bnoqkvtf786l2bcav0.png" alt="console" width="800" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I say ‘handled by the State object’, I mean acknowledges the error and may even address the error. However, any error must then propagate further up to the App’s Error Handler. You don’t want seemingly ‘handled’ errors stopped at a State object’s &lt;strong&gt;onError&lt;/strong&gt;() function. Such an arrangement I feel would be prone to abuse — developers would whole-heartedly stop the propagation and ignore errors! That wouldn’t be good either.&lt;/p&gt;

&lt;p&gt;No, the developers overseeing the app as a whole (i.e. with access to the App’s State object) should have the final say and meet each error in their own Error Handler. Note how Fluttery works for the lone developer as well as in a team environment.&lt;/p&gt;

&lt;p&gt;Further, do you see how Fluttery naturally compartmentalizes the app’s code? I feel Flutter is naturally  ‘State-object-centric’ as the Google engineers intended. Each State object could stand alone as its own particular app in a sense, and this concept is only accentuated using the Fluttery Framework package.&lt;/p&gt;

&lt;p&gt;As for the App State object, it has two Error Handlers. You may have established a third-party Error Handler, and they will catch errors certainly, but these errors will also pass through the &lt;strong&gt;onErrorHandler&lt;/strong&gt;() function and the &lt;strong&gt;inErrorHandler&lt;/strong&gt;() function if you’ve implemented them.&lt;/p&gt;

&lt;p&gt;You’ll find the App’s State object has a number of functions prefixed with ‘on’ and ‘in’ (see &lt;a href="https://dev.to/andrious/little-more-adaptive-5c3k"&gt;Little More Adaptive&lt;/a&gt;). Traditionally, the ‘on’ version, if implemented, will supersede the ‘in-line’ version. However, I’ve placed so much emphasis on Error Handling that I allow for both the ‘on’ and ‘in-line’ versions to run in turn. In my mind, you can’t have enough Error Handling! Implement them both if you want.&lt;/p&gt;

&lt;p&gt;The two screenshots below demonstrate how they’re used. The ‘on’ version is in the first screenshot below — a standalone function called after the third-party Error Handler if any is called, or it’s called on its own in response to an error in the app.  The second screenshot displays the ‘in-line’ version. It’s always found passed to the App State’s constructor, and is always called right after the ‘on’ version.&lt;/p&gt;

&lt;p&gt;You can see I’ve even overridden the State object’s &lt;strong&gt;onError&lt;/strong&gt;() function. You’re free to override it if you must. However, please don’t ignore errors —  it won’t benefit anyone in the end. Regardless, you have complete power over your app’s error handling. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp81eahjmwwr84kdch10i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp81eahjmwwr84kdch10i.png" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/fluttery_framework/blob/master/example/lib/src/app/view/app.dart#L113" rel="noopener noreferrer"&gt;app.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5s8p8pjvlr75izxdclgy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5s8p8pjvlr75izxdclgy.png" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/fluttery_framework/blob/master/example/lib/src/app/view/app.dart#L60" rel="noopener noreferrer"&gt;app.dart&lt;/a&gt;



&lt;p&gt;With Fluttery, you’ve no excuses. Despite your obvious prowess, errors will occur in your code. Fluttery invites you to acknowledge errors where they’re likely to occur — right in the running State object. They then go to the App’s first State object. It’s the class that governs not only how the app looks and behaves, but how it handles its errors as well. &lt;/p&gt;

&lt;p&gt;Cheers.&lt;/p&gt;

&lt;p&gt;→ &lt;a href="https://dev.to/andrious/the-little-more-series-19df"&gt;The ‘Little More’ Series&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/andrious"&gt;→ Other Stories by Greg Perry&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>programming</category>
    </item>
    <item>
      <title>Little More Life Cycle Handling</title>
      <dc:creator>Greg Perry</dc:creator>
      <pubDate>Fri, 26 Jul 2024 17:39:28 +0000</pubDate>
      <link>https://dev.to/andrious/little-more-life-cycle-handling-1fp0</link>
      <guid>https://dev.to/andrious/little-more-life-cycle-handling-1fp0</guid>
      <description>&lt;p&gt;&lt;em&gt;A Little More Framework for the Flutter Framework makes for better apps&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As part of &lt;a href="https://dev.to/andrious/the-little-more-series-19df"&gt;the ‘Little More’ Series&lt;/a&gt;, this article will review the Life cycle events that should be considered when running your app. Events that are made readily available to you when using the [&lt;a href="https://pub.dev/packages/fluttery_framework" rel="noopener noreferrer"&gt;Fluttery Framework&lt;/a&gt;] package.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmnqgp7u9vi6zf0qziymy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmnqgp7u9vi6zf0qziymy.png" width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://blog.devgenius.io/ios-application-life-cycle-672a7eec9d8d" rel="noopener noreferrer"&gt;iOS Application Life Cycle&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flmwi7xjgkbg1airgh5a2.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flmwi7xjgkbg1airgh5a2.jpeg" width="560" height="250"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://developer.android.com/guide/components/activities/activity-lifecycle#alc" rel="noopener noreferrer"&gt;Android Application Life Cycle&lt;/a&gt;



&lt;p&gt;Like its iOS and Android counterparts (see above), Flutter StatefulWidgets have their own life cycle. Below is a graphical depiction of that Life cycle as it’s currently understood. Follow the arrows, and you’re following the ‘sequence of function calls’ when certain circumstances occur. Using the Fluttery Framework, your State object will always have a corresponding function to address any such event — as best as it‘s able anyway.&lt;/p&gt;

&lt;p&gt;You see, Flutter is a cross-platform solution — the Flutter engine runs on top of a completely different operating system depending on the device. As such, there are two separate life cycles involved when it comes to Flutter (denoted in the graphic by the dotted line). Unfortunately, as of this writing, these two life cycles do not acknowledge each other at all.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvni70goa6xxf1015z6ee.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvni70goa6xxf1015z6ee.png" width="800" height="565"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://dev.to/andrious"&gt;Other Stories by Greg Perry&lt;/a&gt;



&lt;p&gt;For example, Flutter will not call a StatefulWidget’s &lt;strong&gt;deactivate&lt;/strong&gt;() and &lt;strong&gt;dispose&lt;/strong&gt;() functions whenever a user has ‘unfocused’ your app with some hand gesture — only to terminate it soon after. For those developers working on the mobile platforms in particular, this has become an issue.&lt;/p&gt;

&lt;p&gt;With Fluttery Framework, however, an effort is made to call the &lt;strong&gt;deactivate&lt;/strong&gt;() and &lt;strong&gt;dispose&lt;/strong&gt;() functions of all the app’s StatefulWidgets whenever such a scenario occurs (See second screenshot below). Unfortunately, as of this writing, it comes down to the particular operating system involved whether they’re called or not:&lt;br&gt;
“&lt;a href="https://github.com/flutter/flutter/issues/57594#issuecomment-1231965622" rel="noopener noreferrer"&gt;AppLifeCycleState.detached is not called when app is closed quickly&lt;/a&gt;”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhyrht0261rnmhbuylqyj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhyrht0261rnmhbuylqyj.png" width="800" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn0gudoilr0cvzcvm82u2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn0gudoilr0cvzcvm82u2.png" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/2c100ddbc724a7da20ea17b1bc9cdab771a0dfdc/lib/state_extended.dart#L2586" rel="noopener noreferrer"&gt;state_extended.dart&lt;/a&gt;



&lt;p&gt;The video below has the example app, &lt;em&gt;widgetsbinding_observer_example&lt;/em&gt;, running on a mobile phone emulator. This app is peppered with &lt;strong&gt;print&lt;/strong&gt;() functions so to convey when particular events are triggered and in which State object. In the video, the app loses focus right away but then is returned to the foreground — only to lose focus again before being terminated. Without intervention, that screen’s &lt;strong&gt;deactivate&lt;/strong&gt;() and &lt;strong&gt;dispose&lt;/strong&gt;() functions would never have been called. The graphic is again presented below for you to compare with the adjacent &lt;strong&gt;print&lt;/strong&gt;() function calls.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AYSPc_NZZomuXoBqE0y0oxQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AYSPc_NZZomuXoBqE0y0oxQ.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9xhtvrcniqphgbln1k4c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9xhtvrcniqphgbln1k4c.png" width="800" height="648"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvni70goa6xxf1015z6ee.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvni70goa6xxf1015z6ee.png" width="800" height="565"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule #2 To Keep In Mind
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Regardless of platform, remember to close databases and other time-critical resources in the **hiddenAppLifeCycleState&lt;/em&gt;&lt;em&gt;() method only to open them again in the method, **resumeAppLifeCycleState&lt;/em&gt;&lt;em&gt;(), if and when the user returns to your app.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This can get really complicated, but the Fluttery Framework is here to help you.&lt;/p&gt;

&lt;p&gt;Another quick example is demonstrated in the video below. Page 1 and Page 2 are two StatefulWidgets called one after the other. The user then returns from Page 2 to Page 1. Again, the example app with its many &lt;strong&gt;print&lt;/strong&gt;() functions details all the events that occur (see below). In this case, you can see when Page2 was closed, the functions, &lt;strong&gt;deactivate&lt;/strong&gt;() and &lt;strong&gt;dispose&lt;/strong&gt;(), are called in quick succession.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A5PBMBwx_wz80Ibp7cbp7BA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A5PBMBwx_wz80Ibp7cbp7BA.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvu61tzw0gtagzwyiw6b1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvu61tzw0gtagzwyiw6b1.png" width="800" height="496"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Better To Deactivate Than Dispose
&lt;/h3&gt;

&lt;p&gt;Remember this: You’ll have no idea when a State object’s &lt;strong&gt;dispose&lt;/strong&gt;() is called — if ever. This function is called by the Flutter engine as part of its ‘garbage collection’ process. It’s to the engine’s discretion when the &lt;strong&gt;dispose&lt;/strong&gt;() function is called (or never called under certain memory constraints), and so, if your StatefulWidgets have any time-critical resources being freed and such, it would be more reliable to do so in their &lt;strong&gt;deactivate&lt;/strong&gt;() functions and not in their &lt;strong&gt;dispose&lt;/strong&gt;() functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule #1 To Keep In Mind
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Regardless of platform, if no longer required by the closing StatefulWidget, remember to close any databases and any time-critical resources in its **deactivate&lt;/em&gt;&lt;em&gt;() method only to open them again in its method, **activate&lt;/em&gt;&lt;em&gt;(), if the running StatefulWidget is not being closed but instead is being moved around the Widget tree (e.g. Reordering items in a ListView widget).&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Series of Events
&lt;/h2&gt;

&lt;p&gt;Let’s quickly go through the event functions calls listed above and suggest what they represent. As you know, when a State object is first created, it is these two functions below that are called. The first State object is called, &lt;em&gt;_AppState.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcsj8d45y1qdyddxahprj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcsj8d45y1qdyddxahprj.png" width="800" height="54"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Fluttery Framework is ‘aware’ a router is involved in this example app, and so the ‘home’ screen with its State object, &lt;em&gt;_Page1State&lt;/em&gt;, is started up and will soon call its &lt;strong&gt;initState&lt;/strong&gt;() function, but not before its event function, &lt;strong&gt;didPush&lt;/strong&gt;(), is called firsr. This allows you to run code ‘when a StatefulWidget is just opened by a Router.’&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3qhhav05di3tp9ewqhl5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3qhhav05di3tp9ewqhl5.png" width="800" height="54"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next two &lt;strong&gt;print&lt;/strong&gt;() functions are displayed below. They tells us ‘Page 1’ is now being displayed with a zero count.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9n0pxrct8nfc2ob7du4x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9n0pxrct8nfc2ob7du4x.png" width="800" height="54"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Because this was run on a mobile phone emulator, the painting and sizing of the app’s interface triggers the &lt;strong&gt;didChangeMetrics&lt;/strong&gt;() in the two StatefulWidgets that make up the app so far. Note, how they’re called in the order they were instantiated — with the help of the Fluttery Framework.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7isgcqd8luxh2b2q9736.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7isgcqd8luxh2b2q9736.png" width="800" height="54"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next line tells Page 1 that the next screen to be displayed has been selected while the second line tells Page 2 it came about because of a router. Note, there’s no reinventing the wheel to achieve this. Fluttery is just implementing what’s already there in Flutter to note these events.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F97rdpltoi6hds6rgb58p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F97rdpltoi6hds6rgb58p.png" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next three lines tells you ‘Page 2’ is now displayed with a count of zero.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3290%2F1%2Aij_iqU0VReya4sDkKAVz5Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3290%2F1%2Aij_iqU0VReya4sDkKAVz5Q.png" width="800" height="74"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the next screenshot below, both the first screen and second screen are notified when the user has returned back to Page 1. Great stuff!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3300%2F1%2AVqTqhmscN3HtuMZo_VsIXA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3300%2F1%2AVqTqhmscN3HtuMZo_VsIXA.png" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Consequently, Page 2 is about to be removed from memory. Therefore, the next two lines appear. Again, the &lt;strong&gt;deactivate&lt;/strong&gt;() is a better place to ‘clean up things’ before returning to the previous screen. The &lt;strong&gt;dispose&lt;/strong&gt;() function just happens to be called right after &lt;strong&gt;deactivate&lt;/strong&gt;() frankly. Under different circumstances beyond your control, it could just as easily never be called.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3300%2F1%2AgoU8lA_JriY7c32XiCK4Fg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3300%2F1%2AgoU8lA_JriY7c32XiCK4Fg.png" width="800" height="54"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Timing is Everything
&lt;/h2&gt;

&lt;p&gt;Playing around with the example app, you’ll discover that Page 5 has a Timer displaying ‘Word Pairs’ introduced in the Flutter website’s codelab called, &lt;a href="https://codelabs.developers.google.com/codelabs/flutter-codelab-first#0" rel="noopener noreferrer"&gt;“First Flutter app”&lt;/a&gt;. See below.&lt;/p&gt;

&lt;p&gt;Look how the Timer object is handled. It’s turned on and turned off when appropriate. You have the ready-means to handle all your running resources effectively and efficiently using Fluttery. Moving on from Page 5 to the next Pages without addressing the Timer object, or an active stream or some other free-running process is just sloppy! In a sense, you’ve just implemented a memory leak otherwise!&lt;/p&gt;

&lt;p&gt;The second screenshot is the very code called when moving from Page 5 to Page 6 and back. Highlighted by the first red arrow is the Timer being turned off while the second red arrow highlights the Timer being turned back on. The first screenshot lists the print statements conveying the event functions involved in the video — its last portion showing the app closing is again displayed further on below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AU8TAQuC0EOO2-CPBvObvUw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AU8TAQuC0EOO2-CPBvObvUw.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F5168%2F1%2AjMNFvDV6u4zro5ATz_2DMQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F5168%2F1%2AjMNFvDV6u4zro5ATz_2DMQ.png" width="800" height="917"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3796%2F1%2AoIj5cySFSAwmUKFit4gVCg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3796%2F1%2AoIj5cySFSAwmUKFit4gVCg.png" alt="[page_05.dart](https://github.com/Andrious/widgetsbinding_observer_example/blob/master/lib/main/view/screens/page_05.dart#L59)" width="800" height="549"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see how the ‘Operating System Events’ are covered by the Fluttery Framework. You can see this by comparing the print statements to the life cycle graphic below. Note, being on a phone emulator running on a laptop, Fluttery even recognizes the memory constraint that occurs by calling the function, &lt;strong&gt;didHaveMemoryPressure&lt;/strong&gt;().&lt;/p&gt;

&lt;p&gt;Look how all the Operating System Event functions in all the State objects currently running in the app all fire in turn and in the order they were instantiated. The host device is up to something, and all the running State objects should be aware of it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F5164%2F1%2A0w5QyInCXjrcDtrMMDcKTQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F5164%2F1%2A0w5QyInCXjrcDtrMMDcKTQ.png" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvni70goa6xxf1015z6ee.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvni70goa6xxf1015z6ee.png" width="800" height="565"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The example app, [&lt;a href="https://github.com/Andrious/widgetsbinding_observer_example" rel="noopener noreferrer"&gt;widgetsbinding_observer_example&lt;/a&gt;], has nine separate screens called one after the other. Note, how the State objects and their accompanying controllers (Business Logic Components like in the BLoC architecture) are triggered in the order they were instantiated.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3024%2F1%2AHd534n_AcpjIuQnknTSRHQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3024%2F1%2AHd534n_AcpjIuQnknTSRHQ.png" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AtVZvPdYAiTM-YrIAFbJwlA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AtVZvPdYAiTM-YrIAFbJwlA.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4850%2F1%2Af9ClPGJcEVRuFLpi6UM4GQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4850%2F1%2Af9ClPGJcEVRuFLpi6UM4GQ.png" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4778%2F1%2A8Dj548p375yoFqHxfdvjqw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4778%2F1%2A8Dj548p375yoFqHxfdvjqw.png" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4776%2F1%2An7Nh3-QwdxdpiAgFNqo-mg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4776%2F1%2An7Nh3-QwdxdpiAgFNqo-mg.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4880%2F1%2AUPlHLU_frOK7OSHVRJLyhg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4880%2F1%2AUPlHLU_frOK7OSHVRJLyhg.png" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Download the example app, [&lt;a href="https://github.com/Andrious/widgetsbinding_observer_example" rel="noopener noreferrer"&gt;widgetsbinding_observer_example&lt;/a&gt;], and see how Fluttery is working for you to make your Flutter app more aware of the platform device it runs on. It’s a necessity if you want a better app.&lt;/p&gt;

&lt;p&gt;Cheers.&lt;/p&gt;

&lt;p&gt;→ &lt;a href="https://dev.to/andrious/the-little-more-series-19df"&gt;The ‘Little More’ Series&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/andrious"&gt;→ Other Stories by Greg Perry&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>programming</category>
    </item>
    <item>
      <title>Little More Adaptive</title>
      <dc:creator>Greg Perry</dc:creator>
      <pubDate>Sat, 20 Jul 2024 15:53:11 +0000</pubDate>
      <link>https://dev.to/andrious/little-more-adaptive-5c3k</link>
      <guid>https://dev.to/andrious/little-more-adaptive-5c3k</guid>
      <description>&lt;p&gt;&lt;em&gt;A Little More Framework for the Flutter Framework makes for better apps&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I began working on this [&lt;a href="https://pub.dev/packages/fluttery_framework" rel="noopener noreferrer"&gt;Fluttery Framework&lt;/a&gt;] package in 2018 to help with my apps — supplying the typical functions and features needed by a production-worthy app.&lt;/p&gt;

&lt;p&gt;As part of &lt;a href="https://dev.to/andrious/the-little-more-series-19df"&gt;the ‘Little More’ Series&lt;/a&gt;, this article will focus on Fluttery’s high adaptivity that is simply achieved by consolidating what Flutter already provides you.&lt;/p&gt;

&lt;p&gt;Flutter apps traditionally begin with a Widget passed to the &lt;strong&gt;runApp&lt;/strong&gt;() function. Using Fluttery, an app starts with a StatefulWidget passed to the &lt;strong&gt;runApp&lt;/strong&gt;() function, and it is called, &lt;em&gt;AppStatefulWidget&lt;/em&gt;. That means a State object called, &lt;em&gt;AppState&lt;/em&gt;, is your app’s first State object and directs your app’s overall appearance and behavior. Below are screenshots of three apps using the Fluttery Framework. Tap them individulally for a closer look. Tapping their corresponding captions will direct you to their source code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F55ylwanp0gw454v2jq5t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F55ylwanp0gw454v2jq5t.png" width="800" height="496"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/fluttery_framework/blob/263f53469cadc510d4e48e1988cfa80751db1204/example/lib/src/app/view/app.dart#L7" rel="noopener noreferrer"&gt;app.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvgyrhcrmukd4ryiat7nv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvgyrhcrmukd4ryiat7nv.png" width="800" height="496"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/pexels_preview/blob/5933a050f8f584ee19809c5eea677878ce2d60c3/lib/app/view/app_view.dart#L7" rel="noopener noreferrer"&gt;app_view.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcxaexzqa096rln699zpj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcxaexzqa096rln699zpj.png" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/fluttery_builder/blob/fa1a76c78dd052ceebf990609dbe393b5a69384e/lib/app/view/app.dart#L10" rel="noopener noreferrer"&gt;app.dart&lt;/a&gt;



&lt;p&gt;If you know Flutter, you’ll know Fluttery. You’ll also know of the many parameters available to you when using the MaterialApp widget or the CupertinoApp widget. All those parameters and more are listed in the AppState class making for a very adaptive Flutter app indeed. See below. You’re free to even use third-party packages like &lt;a href="https://pub.dev/packages/fluent_ui" rel="noopener noreferrer"&gt;Fluent_UI&lt;/a&gt; calling its widget, &lt;em&gt;FluentApp&lt;/em&gt;, instead.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7v78f6dq054o1iki3u4i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7v78f6dq054o1iki3u4i.png" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkkeoz5gexso5n4td6gvg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkkeoz5gexso5n4td6gvg.png" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcfsi6c4q7azbye4j9raf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcfsi6c4q7azbye4j9raf.png" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxdhbctnj2f5b0bs14iia.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxdhbctnj2f5b0bs14iia.png" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/fluttery_framework/blob/263f53469cadc510d4e48e1988cfa80751db1204/lib/view/app_state.dart#L48" rel="noopener noreferrer"&gt;app_state.dart&lt;/a&gt;



&lt;p&gt;One common complaint by seasoned developers now working in Flutter is, because of its declarative approach, the many parameters to a class object in Flutter have to be passed already ‘compiled’ and supplying a value before the ‘App’ State object is even instantiated. The String parameter, &lt;em&gt;title&lt;/em&gt;, found in the MaterialApp and the Cupertino widget is a quick example of this.&lt;/p&gt;

&lt;p&gt;However, many class objects in Flutter do take in a named function as a parameter allowing for a computation to occur only ‘when that parameter value is needed.’ This approach offers more options. The Google engineers themselves knew the value of this because they included a function parameter called, &lt;em&gt;onGenerateTitle&lt;/em&gt;, along with the parameter, &lt;em&gt;title&lt;/em&gt;. For example, doing this allows developers to supply a localized title to their apps by calling the &lt;strong&gt;onGenerateTitle&lt;/strong&gt;() function. If the function parameter, &lt;em&gt;onGenerateTitle&lt;/em&gt;, is passed, it takes precedence over the parameter, &lt;em&gt;title&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;However, most of the remaining parameters in the MaterialApp widget and CupertinoApp widget do not have a function parameter equivalent. It would make an app more adaptive if that was the case. It would allow for more options, more functionality, and more adaptiveness to the developer, wouldn’t it?&lt;/p&gt;

&lt;p&gt;It would.&lt;/p&gt;

&lt;p&gt;Note what’s highlighted with an arrow in the three screenshots below. The first screenshot has the original source code with the traditional parameter, &lt;em&gt;title&lt;/em&gt;, assigned the String, ‘&lt;em&gt;Demo App&lt;/em&gt;’. The next two screenshots only come about using the Fluttery Framework.&lt;/p&gt;

&lt;p&gt;Instead of using the function parameter, &lt;em&gt;onGenerateTitle&lt;/em&gt;, you have the separate &lt;strong&gt;onTitle&lt;/strong&gt;() function to reliably generate your title. In the third screenshot, ‘in-line’ function parameter, &lt;em&gt;onGenerateTitle&lt;/em&gt;, can be replaced with the function parameter, &lt;strong&gt;inTitle&lt;/strong&gt;(), as it too generates the app’s title right there in the constructor. Not the best example. However, this means every parameter now has an ‘on’ and an ‘in-line’ function parameter! This gives you options, and I like options.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpptt95ke9wwg4p8fly3m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpptt95ke9wwg4p8fly3m.png" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4crfqggeshc0p9dtttpg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4crfqggeshc0p9dtttpg.png" width="800" height="496"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj7wg2pb7ev4rvj3i60pj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj7wg2pb7ev4rvj3i60pj.png" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/fluttery_framework/blob/263f53469cadc510d4e48e1988cfa80751db1204/example/lib/src/app/view/app.dart#L19" rel="noopener noreferrer"&gt;app.dart&lt;/a&gt;



&lt;p&gt;With Fluttery, every parameter introduced to you earlier also has a corresponding ‘on’ function allowing you to supply values only when required and, in some instances, only when your app is ready to supply them. This means more capability for you.&lt;/p&gt;

&lt;p&gt;As you see in two screenshots depicting the AppState class below, if an explicit parameter value is not provided (i.e. equals null), the &lt;em&gt;if-null&lt;/em&gt; operator (??) will call the appropriate ‘on’ function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyuha2hiwz7lxgu1r7n3x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyuha2hiwz7lxgu1r7n3x.png" width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/fluttery_framework/blob/263f53469cadc510d4e48e1988cfa80751db1204/lib/view/app_state.dart#L513" rel="noopener noreferrer"&gt;app_state.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkw02i3tkpk96bk0enbbq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkw02i3tkpk96bk0enbbq.png" width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/fluttery_framework/blob/263f53469cadc510d4e48e1988cfa80751db1204/lib/view/app_state.dart#L495" rel="noopener noreferrer"&gt;app_state.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ymn1glppqbptuhvu9h0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ymn1glppqbptuhvu9h0.png" width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/fluttery_framework/blob/263f53469cadc510d4e48e1988cfa80751db1204/lib/view/app_state.dart#L1245" rel="noopener noreferrer"&gt;app_state.dart&lt;/a&gt;



&lt;p&gt;In the first screenshot below, you see how the State object’s &lt;strong&gt;initState&lt;/strong&gt;() function is replaced by its ‘in-line’ counterpart. It’s called right there in the constructor showing the initialization required. However, it behaves like its corresponding ‘on’ function — called only when needed. Another example is the second screenshot showing the supported Locales right there in the constructor call, and how a third-party package deals with the app’s translated text.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Furmn8lfeb4gicc386bgq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Furmn8lfeb4gicc386bgq.png" width="800" height="496"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/fluttery_framework/blob/263f53469cadc510d4e48e1988cfa80751db1204/lib/view/app_state.dart#L513" rel="noopener noreferrer"&gt;app_view.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdejgphkjuvo8g9108tp8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdejgphkjuvo8g9108tp8.png" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/Andrious/pexels_preview/blob/3711434b0a93b0a9bb5f3a6376601630371e704c/lib/app/view/app_view.dart#L37" rel="noopener noreferrer"&gt;app_view.dart&lt;/a&gt;



&lt;p&gt;There’s no re-inventing of the wheel here. It’s just a little tweaking of a great cross-platform solution. Fluttery just makes software development that much more adaptive.&lt;/p&gt;

&lt;p&gt;Cheers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/andrious/the-little-more-series-19df"&gt;→ The ‘Little More’ Series&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/andrious/"&gt;→ Other Stories by Greg Perry&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>programming</category>
    </item>
    <item>
      <title>The ‘Little More’ Series</title>
      <dc:creator>Greg Perry</dc:creator>
      <pubDate>Fri, 19 Jul 2024 19:10:03 +0000</pubDate>
      <link>https://dev.to/andrious/the-little-more-series-19df</link>
      <guid>https://dev.to/andrious/the-little-more-series-19df</guid>
      <description>&lt;h2&gt;
  
  
  The ‘Little More’ Series
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;A Little More Framework for the Flutter Framework makes for better apps&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://dev.to/andrious/little-more-adaptive-5c3k"&gt;Little more Adaptive&lt;/a&gt;&lt;br&gt;
 &lt;a href="https://dev.to/andrious/little-more-life-cycle-handling-1fp0"&gt;Little more Life Cycle Handling&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/andrious/little-more-error-handling-i36"&gt;Little more Error Handling&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/andrious/little-more-control-3o3b"&gt;Little more Control&lt;/a&gt;&lt;br&gt;
Little more Efficient&lt;br&gt;
Little more App&lt;br&gt;
Little more Ability&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’ve always said, as great as Flutter is, you will not create a ‘production-worthy’ app using Flutter right out of the box. Of course, making such a statement is not without some pushback:&lt;/p&gt;

&lt;p&gt;“I don’t understand why I should use and learn some &lt;code&gt;Fluttery Framework&lt;/code&gt;, when I already use and know Flutter.” — &lt;a href="https://www.reddit.com/r/FlutterDev/comments/155xx0d/comment/jt6aodb/" rel="noopener noreferrer"&gt;reddit.com/r/FlutterDev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;“I would definitely say you can build a production-ready app right out of the box, it all depends on the feature requirements.” — &lt;a href="https://www.reddit.com/r/FlutterDev/comments/155xx0d/comment/jtbof9c/" rel="noopener noreferrer"&gt;reddit.com/r/FlutterDev&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prove It
&lt;/h2&gt;

&lt;p&gt;That was about a year ago, and I’m still steadfast in my position. I began the [&lt;a href="https://pub.dev/packages/fluttery_framework" rel="noopener noreferrer"&gt;Fluttery Framework&lt;/a&gt;] package back in 2018 supplying the typical functions and features needed for a production-worthy app. It certainly made my Life easier when building apps as it became a culmination of what Flutter already offered as well as sound Dart packages from the Flutter community. &lt;/p&gt;

&lt;p&gt;Each article in this series will have a title suggesting  what I felt the ‘right out of the box’ Flutter needed a ‘little more’ of  to produce apps ready for release. In most cases, it was simply a matter of implementing the very classes and core packages already found in Flutter. &lt;/p&gt;

&lt;h2&gt;
  
  
  It’s a Choice Not a Chore
&lt;/h2&gt;

&lt;p&gt;My motto has always been ‘Keep It Flutter’ when writing Fluttery. It works with Flutter; not on top of it as a separate approach. It doesn’t impose itself on you. It works with Flutter because it works like Flutter — it looks like Flutter. If you know Flutter, you’ll know Fluttery.&lt;/p&gt;

&lt;p&gt;I needed a framework to quicken the building of Flutter apps; to enhance the building process resulting in a reliable and robust end product. However, as Dave Farley suggests, one that wouldn’t impede my code but fulfill the needs of each unique project. Have I done it? You be the judge.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AvCfj5zuhTSED7DsN.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AvCfj5zuhTSED7DsN.jpeg" alt="[How To Be A Great Programmer](https://www.youtube.com/watch?v=X99Be8wJBMI&amp;amp;t=4m4s)" width="402" height="229"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cheers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/andrious"&gt;→ Other Stories by Greg Perry&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
