{"id":134,"date":"2021-12-05T00:00:00","date_gmt":"2021-12-05T04:00:00","guid":{"rendered":"https:\/\/gerardomiranda.dev\/blog\/?p=134"},"modified":"2021-12-05T11:39:27","modified_gmt":"2021-12-05T15:39:27","slug":"how-to-change-the-color-of-a-flutter-spinbox","status":"publish","type":"post","link":"https:\/\/gerardomiranda.dev\/blog\/how-to-change-the-color-of-a-flutter-spinbox\/","title":{"rendered":"How to change the color of a Flutter SpinBox"},"content":{"rendered":"\n<p>In a previous <a href=\"https:\/\/gerardomiranda.dev\/blog\/my-first-time-contributing-the-open-source-software\/\" title=\"My first time contributing to open source software\">post <\/a> I discussed about my first contribution to open source, and even if it didn&#8217;t turn out precisely as I wanted, I learnt a lot. And now I&#8217;m going to explore the solution to the issue I tried to resolve.<\/p>\n\n\n\n<p>If you didn&#8217;t see my previous post, the issue was basically adding the option to apply the theme to the buttons of a <a href=\"https:\/\/github.com\/jpnurmi\/flutter_spinbox\">spinbox <\/a>in Flutter, because the theme was only applied when the widget was focused. This issue was valid to the material widget only, not the cupertino one.<\/p>\n\n\n\n<p>The solution that was applied not only solves this particular problem, but also covers other scenarios. First using <a href=\"https:\/\/api.flutter.dev\/flutter\/material\/MaterialStateProperty-class.html\">Material State Property<\/a>, and then using an Inherited Theme to complement this functionality, but I think I&#8217;m moving too fast. Let&#8217;s start preparing a simple app to test this.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Preparing the app<\/h4>\n\n\n\n<p>Let&#8217;s execute flutter create in a CLI to generate our new Flutter app.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">flutter create flutter_spinbox_examples<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Now let&#8217;s get rid of all the unnecessary stuff and create 3 spinbox widget that will be our test subjects.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Dart\" data-shcb-language-slug=\"dart\"><span><code class=\"hljs language-dart shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">void<\/span> main() {\n<\/span><\/span><span class='shcb-loc'><span>  runApp(<span class=\"hljs-keyword\">const<\/span> MyApp());\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">MyApp<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">StatelessWidget<\/span> <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> MyApp({Key? key}) : <span class=\"hljs-keyword\">super<\/span>(key: key);\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-comment\">\/\/ This widget is the root of your application.<\/span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-meta\">@override<\/span>\n<\/span><\/span><span class='shcb-loc'><span>  Widget build(BuildContext context) {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">return<\/span> MaterialApp(\n<\/span><\/span><span class='shcb-loc'><span>      title: <span class=\"hljs-string\">'Flutter Demo'<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>      theme: ThemeData(\n<\/span><\/span><span class='shcb-loc'><span>        primarySwatch: Colors.blue,\n<\/span><\/span><span class='shcb-loc'><span>      ),\n<\/span><\/span><span class='shcb-loc'><span>      home: <span class=\"hljs-keyword\">const<\/span> MyHomePage(),\n<\/span><\/span><span class='shcb-loc'><span>    );\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">MyHomePage<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">StatelessWidget<\/span><\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> MyHomePage({Key? key}) : <span class=\"hljs-keyword\">super<\/span>(key: key);\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-meta\">@override<\/span>\n<\/span><\/span><span class='shcb-loc'><span>  Widget build(BuildContext context) {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">return<\/span> Scaffold(\n<\/span><\/span><span class='shcb-loc'><span>      appBar: AppBar(\n<\/span><\/span><span class='shcb-loc'><span>        title: <span class=\"hljs-keyword\">const<\/span> Text(<span class=\"hljs-string\">'Flutter Spinbox Example'<\/span>),\n<\/span><\/span><span class='shcb-loc'><span>      ),\n<\/span><\/span><span class='shcb-loc'><span>      body: ListView(\n<\/span><\/span><span class='shcb-loc'><span>        children: &#91;\n<\/span><\/span><span class='shcb-loc'><span>          SpinBox(\n<\/span><\/span><span class='shcb-loc'><span>            value: <span class=\"hljs-number\">10<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>            decoration: <span class=\"hljs-keyword\">const<\/span> InputDecoration(labelText: <span class=\"hljs-string\">'Control'<\/span>),\n<\/span><\/span><span class='shcb-loc'><span>          ),\n<\/span><\/span><span class='shcb-loc'><span>          SpinBox(\n<\/span><\/span><span class='shcb-loc'><span>            value: <span class=\"hljs-number\">10<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>            decoration: <span class=\"hljs-keyword\">const<\/span> InputDecoration(labelText: <span class=\"hljs-string\">'Material State Property'<\/span>),\n<\/span><\/span><span class='shcb-loc'><span>          ),\n<\/span><\/span><span class='shcb-loc'><span>          SpinBox(\n<\/span><\/span><span class='shcb-loc'><span>            value: <span class=\"hljs-number\">10<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>            decoration: <span class=\"hljs-keyword\">const<\/span> InputDecoration(labelText: <span class=\"hljs-string\">'Inherited Theme'<\/span>),\n<\/span><\/span><span class='shcb-loc'><span>          ),\n<\/span><\/span><span class='shcb-loc'><span>        ],\n<\/span><\/span><span class='shcb-loc'><span>      ),\n<\/span><\/span><span class='shcb-loc'><span>    );\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Dart<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">dart<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638590814-485x1024.png\" alt=\"\" class=\"wp-image-188\" width=\"364\" height=\"768\" srcset=\"https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638590814-485x1024.png 485w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638590814-142x300.png 142w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638590814-768x1621.png 768w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638590814-728x1536.png 728w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638590814-970x2048.png 970w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638590814.png 1080w\" sizes=\"auto, (max-width: 364px) 100vw, 364px\" \/><figcaption>Three spinbox widgets<\/figcaption><\/figure><\/div>\n\n\n\n<p>I think we can do better than that, let&#8217;s add some padding to the spinbox widgets.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Dart\" data-shcb-language-slug=\"dart\"><span><code class=\"hljs language-dart shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span>      body: ListView(\n<\/span><\/span><span class='shcb-loc'><span>        children: &#91;\n<\/span><\/span><span class='shcb-loc'><span>          Padding(\n<\/span><\/span><span class='shcb-loc'><span>            padding: <span class=\"hljs-keyword\">const<\/span> EdgeInsets.all(<span class=\"hljs-number\">16.0<\/span>),\n<\/span><\/span><span class='shcb-loc'><span>            child: SpinBox(\n<\/span><\/span><span class='shcb-loc'><span>              value: <span class=\"hljs-number\">10<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>              decoration: <span class=\"hljs-keyword\">const<\/span> InputDecoration(labelText: <span class=\"hljs-string\">'Control'<\/span>),\n<\/span><\/span><span class='shcb-loc'><span>            ),\n<\/span><\/span><span class='shcb-loc'><span>          ),\n<\/span><\/span><span class='shcb-loc'><span>          Padding(\n<\/span><\/span><span class='shcb-loc'><span>            padding: <span class=\"hljs-keyword\">const<\/span> EdgeInsets.all(<span class=\"hljs-number\">16.0<\/span>),\n<\/span><\/span><span class='shcb-loc'><span>            child: SpinBox(\n<\/span><\/span><span class='shcb-loc'><span>              value: <span class=\"hljs-number\">10<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>              decoration: <span class=\"hljs-keyword\">const<\/span> InputDecoration(labelText: <span class=\"hljs-string\">'Material State Property'<\/span>),\n<\/span><\/span><span class='shcb-loc'><span>            ),\n<\/span><\/span><span class='shcb-loc'><span>          ),\n<\/span><\/span><span class='shcb-loc'><span>          Padding(\n<\/span><\/span><span class='shcb-loc'><span>            padding: <span class=\"hljs-keyword\">const<\/span> EdgeInsets.all(<span class=\"hljs-number\">16.0<\/span>),\n<\/span><\/span><span class='shcb-loc'><span>            child: SpinBox(\n<\/span><\/span><span class='shcb-loc'><span>              value: <span class=\"hljs-number\">10<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>              decoration: <span class=\"hljs-keyword\">const<\/span> InputDecoration(labelText: <span class=\"hljs-string\">'Inherited Theme'<\/span>),\n<\/span><\/span><span class='shcb-loc'><span>            ),\n<\/span><\/span><span class='shcb-loc'><span>          ),\n<\/span><\/span><span class='shcb-loc'><span>        ],\n<\/span><\/span><span class='shcb-loc'><span>      ),\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Dart<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">dart<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638591161-485x1024.png\" alt=\"\" class=\"wp-image-189\" width=\"364\" height=\"768\" srcset=\"https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638591161-485x1024.png 485w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638591161-142x300.png 142w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638591161-768x1621.png 768w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638591161-728x1536.png 728w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638591161-970x2048.png 970w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638591161.png 1080w\" sizes=\"auto, (max-width: 364px) 100vw, 364px\" \/><figcaption>Three spinbox widgets with padding<\/figcaption><\/figure><\/div>\n\n\n\n<p>That&#8217;s much better.<\/p>\n\n\n\n<p>We can see that while the spinbox is unfocused it is gray, as if it is disabled. In some cases this behavior is not a problem, but when we have several spinboxes we can have a better appearance if we match them with the theme, no matter the state of the widgets.<\/p>\n\n\n\n<p>Now let&#8217;s start with the tests.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Material State Property<\/h4>\n\n\n\n<p>With Material State Property you can resolve attributes like the color of the widgets, using its method resolveWith.<\/p>\n\n\n\n<p>In <a href=\"https:\/\/api.flutter.dev\/flutter\/material\/MaterialState-class.html\">MaterialState<\/a> you have the following states: disabled, dragged, error, focused, hovered, pressed, scrolledUnder and selected. In the cas of the Spinbox the state that it exposes are disabled, focused and error.<\/p>\n\n\n\n<p>We are going to resolve this 3 states in our second spinbox for the iconColor property.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Dart\" data-shcb-language-slug=\"dart\"><span><code class=\"hljs language-dart shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span>          Padding(\n<\/span><\/span><span class='shcb-loc'><span>            padding: <span class=\"hljs-keyword\">const<\/span> EdgeInsets.all(<span class=\"hljs-number\">16.0<\/span>),\n<\/span><\/span><span class='shcb-loc'><span>            child: SpinBox(\n<\/span><\/span><span class='shcb-loc'><span>              value: <span class=\"hljs-number\">10<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>              decoration: <span class=\"hljs-keyword\">const<\/span> InputDecoration(labelText: <span class=\"hljs-string\">'Material State Property'<\/span>),\n<\/span><\/span><span class='shcb-loc'><span>              iconColor: MaterialStateProperty.resolveWith((states) {\n<\/span><\/span><span class='shcb-loc'><span>                  <span class=\"hljs-keyword\">if<\/span> (states.contains(MaterialState.disabled)) {\n<\/span><\/span><span class='shcb-loc'><span>                    <span class=\"hljs-keyword\">return<\/span> Colors.grey;\n<\/span><\/span><span class='shcb-loc'><span>                  }\n<\/span><\/span><span class='shcb-loc'><span>                  <span class=\"hljs-keyword\">if<\/span> (states.contains(MaterialState.error)) {\n<\/span><\/span><span class='shcb-loc'><span>                    <span class=\"hljs-keyword\">return<\/span> Colors.red;\n<\/span><\/span><span class='shcb-loc'><span>                  }\n<\/span><\/span><span class='shcb-loc'><span>                  <span class=\"hljs-keyword\">if<\/span> (states.contains(MaterialState.focused)) {\n<\/span><\/span><span class='shcb-loc'><span>                    <span class=\"hljs-keyword\">return<\/span> Colors.green;\n<\/span><\/span><span class='shcb-loc'><span>                  }\n<\/span><\/span><span class='shcb-loc'><span>                }\n<\/span><\/span><span class='shcb-loc'><span>              ),\n<\/span><\/span><span class='shcb-loc'><span>            ),\n<\/span><\/span><span class='shcb-loc'><span>          ),\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Dart<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">dart<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>But now the only thing that changed is that the button icons are now black. This is because in this moment the spinbox doesn&#8217;t have any state. If you tap on the spinbox the button icons are going to be green, but as soon as you change the focus the color goes back to black.<\/p>\n\n\n\n<p>What we need, is to resolve the color when the state is not between those 3 states that are exposed. So we are going to add a default color, returning Colors.blue after the if statements.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Dart\" data-shcb-language-slug=\"dart\"><span><code class=\"hljs language-dart shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">return<\/span> Colors.blue;\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Dart<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">dart<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638583469-485x1024.png\" alt=\"\" class=\"wp-image-190\" width=\"364\" height=\"768\" srcset=\"https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638583469-485x1024.png 485w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638583469-142x300.png 142w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638583469-768x1621.png 768w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638583469-728x1536.png 728w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638583469-970x2048.png 970w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638583469.png 1080w\" sizes=\"auto, (max-width: 364px) 100vw, 364px\" \/><figcaption>Second spinbox with MaterialStateProperty<\/figcaption><\/figure><\/div>\n\n\n\n<p>Now the buttons icon color is going to be blue by default, until you tap on it, then it is going to be green.<\/p>\n\n\n\n<p>For the next option we are going to explore how to achieve the same thing, but for several spinbox at a time.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Inherited Theme<\/h4>\n\n\n\n<p>Now that we know how to use MaterialStateProperty to change the color of our spinbox, if we have several spinboxes across our application we probably don&#8217;t want to repeat this code in every spinbox, so for that we have the SpinBoxTheme widget.<\/p>\n\n\n\n<p>SpinBoxTheme is an InheritedWidget, which means any data we define in this widget is going to be spread down the widget tree.<\/p>\n\n\n\n<p>To see SpinBoxTheme in action we need to add one more spinbox, so lets add it and wrap both with a Column widget.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Dart\" data-shcb-language-slug=\"dart\"><span><code class=\"hljs language-dart shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span>            Column(\n<\/span><\/span><span class='shcb-loc'><span>              children: &#91;\n<\/span><\/span><span class='shcb-loc'><span>                Padding(\n<\/span><\/span><span class='shcb-loc'><span>                  padding: <span class=\"hljs-keyword\">const<\/span> EdgeInsets.all(<span class=\"hljs-number\">16.0<\/span>),\n<\/span><\/span><span class='shcb-loc'><span>                  child: SpinBox(\n<\/span><\/span><span class='shcb-loc'><span>                    value: <span class=\"hljs-number\">10<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>                    decoration: <span class=\"hljs-keyword\">const<\/span> InputDecoration(labelText: <span class=\"hljs-string\">'Inherited Theme 1'<\/span>),\n<\/span><\/span><span class='shcb-loc'><span>                  ),\n<\/span><\/span><span class='shcb-loc'><span>                ),\n<\/span><\/span><span class='shcb-loc'><span>                Padding(\n<\/span><\/span><span class='shcb-loc'><span>                  padding: <span class=\"hljs-keyword\">const<\/span> EdgeInsets.all(<span class=\"hljs-number\">16.0<\/span>),\n<\/span><\/span><span class='shcb-loc'><span>                  child: SpinBox(\n<\/span><\/span><span class='shcb-loc'><span>                    value: <span class=\"hljs-number\">10<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>                    decoration: <span class=\"hljs-keyword\">const<\/span> InputDecoration(labelText: <span class=\"hljs-string\">'Inherited Theme 2'<\/span>),\n<\/span><\/span><span class='shcb-loc'><span>                  ),\n<\/span><\/span><span class='shcb-loc'><span>                ),\n<\/span><\/span><span class='shcb-loc'><span>              ]\n<\/span><\/span><span class='shcb-loc'><span>            )\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Dart<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">dart<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>And now wrap the Column with a SpinBoxTheme, you will notice the data property is mandatory. This property is of the class SpinBoxThemeDate and the attribute we are going to define is iconColor. The same property we define in our previous example. Here we are going to define our MaterialStateProperty.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Dart\" data-shcb-language-slug=\"dart\"><span><code class=\"hljs language-dart\">            SpinBoxThemeData(\n              iconColor: MaterialStateProperty.resolveWith((states) {\n                <span class=\"hljs-keyword\">return<\/span> Colors.red;\n              })\n            )<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Dart<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">dart<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Since we already covered the state in the previous section, we are going to keep it simple and return just the red color regardless of the state, now this is the final code for the SpinBoxTheme with both spinboxes within:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Dart\" data-shcb-language-slug=\"dart\"><span><code class=\"hljs language-dart shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span>          SpinBoxTheme(\n<\/span><\/span><span class='shcb-loc'><span>            data: SpinBoxThemeData(\n<\/span><\/span><span class='shcb-loc'><span>              iconColor: MaterialStateProperty.resolveWith((states) {\n<\/span><\/span><span class='shcb-loc'><span>                <span class=\"hljs-keyword\">return<\/span> Colors.red;\n<\/span><\/span><span class='shcb-loc'><span>              })\n<\/span><\/span><span class='shcb-loc'><span>            ),\n<\/span><\/span><span class='shcb-loc'><span>            child: Column(\n<\/span><\/span><span class='shcb-loc'><span>              children: &#91;\n<\/span><\/span><span class='shcb-loc'><span>                Padding(\n<\/span><\/span><span class='shcb-loc'><span>                  padding: <span class=\"hljs-keyword\">const<\/span> EdgeInsets.all(<span class=\"hljs-number\">16.0<\/span>),\n<\/span><\/span><span class='shcb-loc'><span>                  child: SpinBox(\n<\/span><\/span><span class='shcb-loc'><span>                    value: <span class=\"hljs-number\">10<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>                    decoration: <span class=\"hljs-keyword\">const<\/span> InputDecoration(labelText: <span class=\"hljs-string\">'Inherited Theme 1'<\/span>),\n<\/span><\/span><span class='shcb-loc'><span>                  ),\n<\/span><\/span><span class='shcb-loc'><span>                ),\n<\/span><\/span><span class='shcb-loc'><span>                Padding(\n<\/span><\/span><span class='shcb-loc'><span>                  padding: <span class=\"hljs-keyword\">const<\/span> EdgeInsets.all(<span class=\"hljs-number\">16.0<\/span>),\n<\/span><\/span><span class='shcb-loc'><span>                  child: SpinBox(\n<\/span><\/span><span class='shcb-loc'><span>                    value: <span class=\"hljs-number\">10<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>                    decoration: <span class=\"hljs-keyword\">const<\/span> InputDecoration(labelText: <span class=\"hljs-string\">'Inherited Theme 2'<\/span>),\n<\/span><\/span><span class='shcb-loc'><span>                  ),\n<\/span><\/span><span class='shcb-loc'><span>                ),\n<\/span><\/span><span class='shcb-loc'><span>              ]\n<\/span><\/span><span class='shcb-loc'><span>            )\n<\/span><\/span><span class='shcb-loc'><span>          ),\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Dart<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">dart<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638587653-485x1024.png\" alt=\"\" class=\"wp-image-192\" width=\"364\" height=\"768\" srcset=\"https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638587653-485x1024.png 485w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638587653-142x300.png 142w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638587653-768x1621.png 768w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638587653-728x1536.png 728w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638587653-970x2048.png 970w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638587653.png 1080w\" sizes=\"auto, (max-width: 364px) 100vw, 364px\" \/><figcaption>Third and fouth spinbox with SpinBoxTheme<\/figcaption><\/figure><\/div>\n\n\n\n<h4 class=\"wp-block-heading\">Precedence Order<\/h4>\n\n\n\n<p>As a final point, I wan to add that there is an precedence order in this methods to use them simultaneously in our app.<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>MaterialStateProperty in the SpinBox iconColor property.<\/li><li>MaterialStateProperty in the SpinBoxTheme, the closest one in the widget tree is taken.<\/li><li>Theme colors: This are only applied when the widget is focused.<\/li><\/ol>\n\n\n\n<p>If you have several SpinBoxTheme widgets in the widget tree, the spinbox is going to resolve the closest one in the widget tree. For example you can have a SpinBoxTheme at the top of you entire application, and another one for only a group of spinboxes, the closest one is going to take precedence.<\/p>\n\n\n\n<p>To test this you can wrap the MaterialApp widget with a SpinBoxTheme that returns the yellow color for all states and you will see that only the first spinbox is going to change to yellow.<\/p>\n\n\n\n<p>And now if you remove the SpinBoxTheme that defines the red color, all spinboxes are going to be yellow except for the second one that has defined its iconColor property.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Dart\" data-shcb-language-slug=\"dart\"><span><code class=\"hljs language-dart shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-meta\">@override<\/span>\n<\/span><\/span><span class='shcb-loc'><span>  Widget build(BuildContext context) {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">return<\/span> SpinBoxTheme(\n<\/span><\/span><span class='shcb-loc'><span>      data: SpinBoxThemeData(\n<\/span><\/span><span class='shcb-loc'><span>        iconColor: MaterialStateProperty.resolveWith((states) =&gt; Colors.yellow),\n<\/span><\/span><span class='shcb-loc'><span>      ),\n<\/span><\/span><span class='shcb-loc'><span>      child: MaterialApp(\n<\/span><\/span><span class='shcb-loc'><span>        title: <span class=\"hljs-string\">'Flutter Demo'<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>        theme: ThemeData(\n<\/span><\/span><span class='shcb-loc'><span>          primarySwatch: Colors.blue,\n<\/span><\/span><span class='shcb-loc'><span>        ),\n<\/span><\/span><span class='shcb-loc'><span>        home: <span class=\"hljs-keyword\">const<\/span> MyHomePage(),\n<\/span><\/span><span class='shcb-loc'><span>      ),\n<\/span><\/span><span class='shcb-loc'><span>    );\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Dart<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">dart<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638589246-485x1024.png\" alt=\"\" class=\"wp-image-193\" width=\"364\" height=\"768\" srcset=\"https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638589246-485x1024.png 485w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638589246-142x300.png 142w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638589246-768x1621.png 768w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638589246-728x1536.png 728w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638589246-970x2048.png 970w, https:\/\/gerardomiranda.dev\/blog\/wp-content\/uploads\/2021\/12\/Screenshot_1638589246.png 1080w\" sizes=\"auto, (max-width: 364px) 100vw, 364px\" \/><\/figure><\/div>\n\n\n\n<h4 class=\"wp-block-heading\">Final words<\/h4>\n\n\n\n<p>I hope you found this post useful. As always <a href=\"https:\/\/github.com\/gerardo-m\/flutter_spinbox_examples\">here <\/a>is the source code so you can explore it and test it yourself.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8230;covers other scenarios. First using Material State Property, and then using an Inherited Theme to complement this functionality<\/p>\n","protected":false},"author":1,"featured_media":216,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[24],"tags":[33],"class_list":["post-134","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-learning","tag-flutter"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/gerardomiranda.dev\/blog\/wp-json\/wp\/v2\/posts\/134","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gerardomiranda.dev\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gerardomiranda.dev\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gerardomiranda.dev\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gerardomiranda.dev\/blog\/wp-json\/wp\/v2\/comments?post=134"}],"version-history":[{"count":15,"href":"https:\/\/gerardomiranda.dev\/blog\/wp-json\/wp\/v2\/posts\/134\/revisions"}],"predecessor-version":[{"id":217,"href":"https:\/\/gerardomiranda.dev\/blog\/wp-json\/wp\/v2\/posts\/134\/revisions\/217"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/gerardomiranda.dev\/blog\/wp-json\/wp\/v2\/media\/216"}],"wp:attachment":[{"href":"https:\/\/gerardomiranda.dev\/blog\/wp-json\/wp\/v2\/media?parent=134"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gerardomiranda.dev\/blog\/wp-json\/wp\/v2\/categories?post=134"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gerardomiranda.dev\/blog\/wp-json\/wp\/v2\/tags?post=134"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}