{"id":183,"date":"2021-12-05T00:00:00","date_gmt":"2021-12-05T04:00:00","guid":{"rendered":"https:\/\/gerardomiranda.dev\/blog\/?p=183"},"modified":"2021-12-04T12:39:23","modified_gmt":"2021-12-04T16:39:23","slug":"como-personalizar-el-color-de-un-flutter_spinbox","status":"publish","type":"post","link":"https:\/\/gerardomiranda.dev\/blog\/es\/como-personalizar-el-color-de-un-flutter_spinbox\/","title":{"rendered":"C\u00f3mo personalizar el color de un flutter_spinbox"},"content":{"rendered":"\n<p>En un <a href=\"https:\/\/gerardomiranda.dev\/blog\/es\/mi-primera-vez-contribuyendo-al-open-source\/\" title=\"Mi primera vez contribuyendo al open source\">post <\/a>anterior discut\u00ed sobre mi primera colaboraci\u00f3n al open source, y vimos que no sali\u00f3 precisamente como quer\u00eda pero aprend\u00ed bastante. Por eso hoy voy a revisar la soluci\u00f3n que se aplic\u00f3 al issue que trat\u00e9 de resolver.<\/p>\n\n\n\n<p>Por si no lo recuerdan, o no fueron a ver mi anterior post, b\u00e1sicamente el issue trataba de aplicar el tema a los botones del spinbox en flutter porque \u00e9ste s\u00f3lo era aplicado cuando el widget estaba con el focus. Hay que recalcar que el issue solo aplicaba al material widget y no al de cupertino.<\/p>\n\n\n\n<p>La soluci\u00f3n aplicada no solamente resuelve este problema en particular, pero tambi\u00e9n prev\u00e9 otros escenarios. Primero usando <a href=\"https:\/\/api.flutter.dev\/flutter\/material\/MaterialStateProperty-class.html\">Material State Property<\/a> y luego utilizando un Inherited Theme para complementar esta funcionalidad, pero ya me estoy adelantando. Comencemos preparando una app sencilla para probar estas adiciones.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Preparando la app<\/h4>\n\n\n\n<p>Ejecutamos flutter create flutter_spinbox_examples en la consola para generar una nueva aplicaci\u00f3n de flutter. <\/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>Luego borramos todo lo que no necesitamos y creamos 3 spinbox que ser\u00e1n nuestros widgets para comparar.<\/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>Tres spinbox<\/figcaption><\/figure><\/div>\n\n\n\n<p>Creo que podemos hacer algo mejor que esto, a\u00f1adamos padding alrededor de nuestros spinbox.<\/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>Tres spinbox con padding<\/figcaption><\/figure><\/div>\n\n\n\n<p>Mucho mejor.<\/p>\n\n\n\n<p>Podemos ver que mientras el spinbox se encuentra unfocused est\u00e1 completamente gris, como si estuviera deshabilitado. En algunos casos esto no es problema, pero cuando tenemos varios spinbox juntos podr\u00eda verse mejor si mantenemos el color uniforme independientemente del estado.<\/p>\n\n\n\n<p>Por ello vamos a probar las dos formas que fueron a\u00f1adidas.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Material State Property<\/h4>\n\n\n\n<p>Con Material State Property puedes resolver caracter\u00edsticas c\u00f3mo el color de los widgets, utilizando el m\u00e9todo resolveWith.<\/p>\n\n\n\n<p>En <a href=\"https:\/\/api.flutter.dev\/flutter\/material\/MaterialState-class.html\">MaterialState<\/a> tienes los estados: disabled, dragged, error, focused, hovered, pressed, scrolledUnder y selected. En el caso del spinbox, los estados que proporciona son solamente disabled, focused y error.<\/p>\n\n\n\n<p>Vamos a resolver estos 3 estados en nuestro segundo spinbox para el atributo iconColor.<\/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>Pero lo \u00fanico que cambi\u00f3 fue que los \u00edconos ahora son negros. Esto es porque en este momento el spinbox no est\u00e1 en  ning\u00fan estado. Si tocas el spinbox, los \u00edconos de los botones se vuelven verdes, pero tan pronto como cambias el focus, el color vuelve a ser negro.<\/p>\n\n\n\n<p>Lo que nos falta es agregar lo siguiente despu\u00e9s de los if para resolver el color cuando el spinbox no est\u00e1 en ninguno de los estados.<\/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>Segundo spinbox con MaterialStateProperty<\/figcaption><\/figure><\/div>\n\n\n\n<p>Ahora el color de los \u00edconos de los botones ser\u00e1 siempre azul, y si le das el focus cambiar\u00e1n a verde.<\/p>\n\n\n\n<p>Para nuestra siguiente opci\u00f3n exploraremos c\u00f3mo podemos hacer esto mismo, pero para varios spinbox a la vez.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Inherited Theme<\/h4>\n\n\n\n<p>Ahora que sabemos utilizar MaterialStateProperty para cambiar el color de nuestro spinbox, cuando tengamos varios spinbox en nuestra aplicaci\u00f3n probablemente no querremos repetir el mismo c\u00f3digo para cada uno de nuestros spinbox.<\/p>\n\n\n\n<p>Para esto el widget nos provee la clase SpinBoxTheme. Que es un InheritedWidget, lo que quiere decir que los datos que definamos en este widget van a poder ser accedidos por todos sus hijos. <\/p>\n\n\n\n<p>Para ver el SpinboxTheme en acci\u00f3n parece ser que necesitaremos agregar un widget spinbox m\u00e1s, as\u00ed que agregu\u00e9moslo y rodeemos ambos spinbox con un Column.<\/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>Ahora rodeemos el Column con un SpinBoxTheme, y ver\u00e1s que nos pide que definamos el atributo data, este atributo debe ser de la clase SpinBoxThemeData que tiene un atributo llamado iconColor al igual que nuestro Spinbox. En este atributo definiremos nuestro MaterialStateProperty.resolveWith.<\/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>C\u00f3mo ya vimos los estados en el subt\u00edtulo anterior, vamos a mantenerlo simple y retornaremos siempre el color rojo. El resultado final ser\u00e1 el siguiente:<\/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>Tercer y cuarto spinbox con SpinBoxTheme<\/figcaption><\/figure><\/div>\n\n\n\n<h4 class=\"wp-block-heading\">Orden de precedencia<\/h4>\n\n\n\n<p>Para finalizar, quiero agregar que dentro de un Spinbox existe un orden de precedencia para poder utilizar estos dos m\u00e9todos simult\u00e1neamente.<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>MaterialStateProperty directo en el atributo iconColor.<\/li><li>MaterialStateProperty del SpinBoxTheme m\u00e1s cercano en el \u00e1rbol de widgets.<\/li><li>Colores del tema: que s\u00f3lo se utilizan cuando el widget tiene el focus.<\/li><\/ol>\n\n\n\n<p>Si tienes m\u00e1s de un SpinBoxTheme en tu aplicaci\u00f3n, el spinbox va a resolver el m\u00e1s cercano en el widget tree. Es decir, si tienes un SpinBoxTheme definido para toda tu aplicaci\u00f3n y tienes otro definido m\u00e1s abajo, un spinbox bajo este \u00faltimo va a resolver su iconColor usando este \u00faltimo SpinBoxTheme. De esta forma puedes definir un SpinBoxTheme global y tener secciones en las que puedes sobrescribir su comportamiento a\u00f1adiendo otro SpinBoxTheme.<\/p>\n\n\n\n<p>Por ejemplo puedes hacer la prueba rodeando el widget MaterialApp con un SpinBoxTheme que retorne el color amarillo y ver\u00e1s que s\u00f3lo el primer spinbox cambiar\u00e1 de color, ahora quita el SpinBoxTheme que define el color rojo m\u00e1s abajo y todos los spinbox cambiar\u00e1n a color amarillo excepto el segundo que ya tiene definido su iconColor.<\/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\">Palabras finales<\/h4>\n\n\n\n<p>Espero que este art\u00edculo te haya sido de utilidad. Como siempre te dej\u00f3 <a href=\"https:\/\/github.com\/gerardo-m\/flutter_spinbox_examples\">aqu\u00ed <\/a>el c\u00f3digo fuente para que lo puedas ver completo.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8230;tambi\u00e9n prev\u00e9 otros escenarios. Primero usando Material State Property y luego utilizando un Inherited Theme para complementar esta funcionalidad<\/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":[28],"tags":[33],"class_list":["post-183","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-aprendizaje","tag-flutter"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/gerardomiranda.dev\/blog\/wp-json\/wp\/v2\/posts\/183","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=183"}],"version-history":[{"count":13,"href":"https:\/\/gerardomiranda.dev\/blog\/wp-json\/wp\/v2\/posts\/183\/revisions"}],"predecessor-version":[{"id":214,"href":"https:\/\/gerardomiranda.dev\/blog\/wp-json\/wp\/v2\/posts\/183\/revisions\/214"}],"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=183"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gerardomiranda.dev\/blog\/wp-json\/wp\/v2\/categories?post=183"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gerardomiranda.dev\/blog\/wp-json\/wp\/v2\/tags?post=183"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}