<?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: flutterbrasil</title>
    <description>The latest articles on DEV Community by flutterbrasil (@flutterbrasil).</description>
    <link>https://dev.to/flutterbrasil</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%2Forganization%2Fprofile_image%2F8684%2F072e9897-af71-46c6-811a-e8debd731d9c.png</url>
      <title>DEV Community: flutterbrasil</title>
      <link>https://dev.to/flutterbrasil</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/flutterbrasil"/>
    <language>en</language>
    <item>
      <title>Macros no Flutter/Dart: A Revolução da Metaprogramação que Você Esperava</title>
      <dc:creator>Toshi Ossada</dc:creator>
      <pubDate>Mon, 24 Jun 2024 15:12:33 +0000</pubDate>
      <link>https://dev.to/flutterbrasil/macros-no-flutterdart-a-revolucao-da-metaprogramacao-que-voce-esperava-42mi</link>
      <guid>https://dev.to/flutterbrasil/macros-no-flutterdart-a-revolucao-da-metaprogramacao-que-voce-esperava-42mi</guid>
      <description>&lt;h3&gt;
  
  
  Macros no Flutter/Dart: A Revolução da Metaprogramação que Você Esperava
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AZ8p1c-66_HrKcMmu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AZ8p1c-66_HrKcMmu.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fala Devs,&lt;/p&gt;

&lt;p&gt;No ultimo Google I/O tivemos muitas novidades, e uma delas que era uma das mais esperadas foi a confirmação dos Macros para fase experimental (que significa que logo sairá pra stable).&lt;/p&gt;

&lt;p&gt;Mas o que são Macros?&lt;/p&gt;

&lt;p&gt;Macros são um recurso que visa revolucionar a metaprogramação, ou seja, a habilidade de escrever código que manipula outros códigos.&lt;/p&gt;

&lt;p&gt;Mas o que isso significa?&lt;/p&gt;

&lt;p&gt;Imagine uma tarefa comum que realizamos com frequência hoje toJson() e fromJson().&lt;/p&gt;

&lt;p&gt;Hoje temos duas maneiras de realizar essa tarefa, podemos simplesmente fazer os métodos na mão.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


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

&lt;p&gt;O problema desse método é que toda hora que precisamos adicionar um campo novo é no mínimo em 3 lugares que precisamos fazer alteração, um processo que pode ser chato.&lt;/p&gt;

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

&lt;p&gt;Outra forma é utilizarmos uma biblioteca terceira que irá gerar todo esse código com a ajuda do odiado build_runner, como por exemplo o json_serializable&lt;/p&gt;

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

&lt;p&gt;Nesse caso temos alguns fatos que podem frustrar os desenvolvedores, primeiro é que preciso adicionar um “quase” extenso boilerplate&lt;/p&gt;

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

&lt;p&gt;E “outro” problema é que toda alteração precisamos executar novamente o build_runner, as vezes não é um processo tão demorado, entretanto se torna um processo chato de ter que executar o build_runner em toda alteração&lt;/p&gt;

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

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

&lt;p&gt;Hoje temos que fazer estes processos pois no dart que está embedado no Flutter é nerfado e não temos a possibilidade de utilizar &lt;strong&gt;Reflections&lt;/strong&gt; ou as famigeradas &lt;strong&gt;Mirrors&lt;/strong&gt; alegando que há trade-off que talvez não valeria a pena para habilitar as Mirros no Flutter.&lt;/p&gt;

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

&lt;p&gt;Mas calma, a equipe do Flutter não deu as costas e ignorou este problema. No Flutter Foward que ocorreu ano passado (2023) eles anunciaram que iriam começar a trabalhar em uma nova feature para resolver este problema, eles anunciaram que brevemente iriam lançar as Macros.&lt;/p&gt;

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

&lt;p&gt;Depois de muita espera, chegaram até rolar boatos que eles iriam desistir das macros, neste Google I/O (2024) eles anunciaram que já encontra em fase experimental.&lt;/p&gt;

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

&lt;p&gt;Para começar a testar as macros precisamos ter em mente que ainda está em fase experimental, então não está disponível no canal &lt;strong&gt;stable&lt;/strong&gt; (Espero que você esteja usando esse canal para desenvolver sus apps) então nossa primeira tarefa para habilitar a utilização dos macros é apontar para o canal master&lt;/p&gt;

&lt;p&gt;Execute:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;flutter channel master&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;Isso fará com que apontemos para o dart 3.5&lt;/p&gt;

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

&lt;p&gt;E se executarmos o comando flutter channel irá nos apresentar que está apontando para a master com um asterisco (*)&lt;/p&gt;

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

&lt;p&gt;Outra etapa (caso use visual studio code) é apontarmos as extensões do dart e flutter para a pré release, procure as extensões e pressione o botão “switch to Pre-Release Version”&lt;/p&gt;

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

&lt;p&gt;Faça o mesmo procedimento para o Flutter&lt;/p&gt;

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

&lt;p&gt;Precisamos também habilitar no analysis_options.yaml a feature experimental dos macros&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


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

&lt;p&gt;Pronto agora já podemos utilizar a macros, algo bom que é que não partiremos de um mundo que teremos que criar todas as macros pois a equipe do Dart em paralelo já está desenvolvendo alguns macros que para utiliza-los basta importar em nosso projeto e para esse processo que citamos acima do toJson() e fromJson() existe o pacote json que está publicado por &lt;strong&gt;labs.dart.dev&lt;/strong&gt; (publicador da equipe do dart para pacotes que estão em experimental)&lt;/p&gt;

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

&lt;p&gt;Para adicionar basta executar um &lt;strong&gt;pub add&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;Para utiliza-lo basta colocarmos a annotation em nossa classe &lt;strong&gt;@JsonCodable()&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;Note que no VS Code ele habilitou um botão “Go to Augmentation” se clicarmos nele podemos ver os macros que foram gerados&lt;/p&gt;

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

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

&lt;p&gt;E se alterar o código da classe e salvar ele automaticamente vai alterar minhas macros&lt;/p&gt;

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

&lt;p&gt;Impressionante a velocidade&lt;/p&gt;

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

&lt;p&gt;Outro ponto legal é que também podemos fazer nossos próprios macros, vamos então automatizar a geração do toString()&lt;/p&gt;

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

&lt;p&gt;Notamos que iremos necessitar de 2 informações da classe, o nome da classe e os campos&lt;/p&gt;

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

&lt;p&gt;Para criar uma classe iremos criar uma class com o modificador macro e devemos implementar a ClassDeclaration, um ponto importante é que fica obrigatório a criação de um construtor que seja constante.&lt;/p&gt;

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

&lt;p&gt;Feito isso implementamos o método &lt;strong&gt;buildDeclarationsForClass&lt;/strong&gt; que tem dois parâmetros, a &lt;strong&gt;clazz&lt;/strong&gt; (está com Z pois class é uma palavra reservada do dart) que é onde irá conter as informações da classe (como o nome da classe) e também temos o &lt;strong&gt;builder&lt;/strong&gt; que iremos utilizar para gerar o código na macro.&lt;/p&gt;

&lt;p&gt;Para recuperar o nome da classe utilizamos o clazz.identifier.name e para recuperar os atributos da classe utilizamos o &lt;strong&gt;builder.fieldsOf(clazz)&lt;/strong&gt; lembrando que ele é uma Feature então precisamos usar o &lt;strong&gt;await&lt;/strong&gt; na execução do método e adicionar o &lt;strong&gt;async&lt;/strong&gt; na função.&lt;/p&gt;

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

&lt;p&gt;Para gerar o código utilizaremos o builder.declareIntype() e geraremos o código em uma String que podemos separar por virgula(,) para que não fique uma linha gigantesca&lt;/p&gt;

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

&lt;p&gt;Ressaltando que a saída do nosso código será “campo: $campo” então é necessário adicionar o &lt;strong&gt;&amp;amp;&lt;/strong&gt; com a tag escape na frente (*&lt;em&gt;*&lt;/em&gt;).&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Para utiliza-lo em nossa classe basta adicionar a annotation que será o mesmo nome do macro criado.&lt;/p&gt;

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

&lt;p&gt;E ele automaticamente irá gerar o código no macro&lt;/p&gt;

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

&lt;p&gt;Agora podemos utiliza-lo em nosso main.dart&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Para executar precisamos adicionar a tag — enable-experiment=macros&lt;/p&gt;

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

&lt;p&gt;Ou podemos também deixar configurado em nosso launch.json&lt;/p&gt;

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

&lt;p&gt;Ressaltando novamente que os macros está em fase experimental e podemos ter alguns bugs que estão sendo corrigidos pela equipe do Dart, mas esperamos que logo(talvez ainda esse ano) já sairá uma versão em em stable para nós deliciar com os macros.&lt;/p&gt;

&lt;p&gt;Se quiser ler mais a respeito das macros visite &lt;a href="https://dart.dev/go/macros" rel="noopener noreferrer"&gt;https://dart.dev/go/macros&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tembém gravei um video no canal da Flutter Brasil de como podemos utilizar os macros, confira:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=AjA4sJR2CN8" rel="noopener noreferrer"&gt;&lt;br&gt;
 &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.youtube.com%2Fvi%2FAjA4sJR2CN8%2F0.jpg" alt="Monorepo (Por Que Essa Estratégia Funciona em Grandes Empresas?) "&gt;&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Entre em nosso discord para interagir com a comunidade e ficar por dentro de todas as nossas publicações: &lt;a href="https://www.flutterbrasil.com.br" rel="noopener noreferrer"&gt;https://www.flutterbrasil.com.br&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dart</category>
      <category>metaprogramming</category>
      <category>macros</category>
    </item>
    <item>
      <title>Flutter 3.22 e Dart 3.4: Confira as atualizações que roloram no Google I/O 2024</title>
      <dc:creator>Toshi Ossada</dc:creator>
      <pubDate>Sat, 18 May 2024 14:06:17 +0000</pubDate>
      <link>https://dev.to/flutterbrasil/flutter-322-e-dart-34-confira-as-atualizacoes-que-roloram-no-google-io-2024-2d4n</link>
      <guid>https://dev.to/flutterbrasil/flutter-322-e-dart-34-confira-as-atualizacoes-que-roloram-no-google-io-2024-2d4n</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PtG0iRBG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/0%2AVKDPcLqGSThJ1mMZ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PtG0iRBG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/0%2AVKDPcLqGSThJ1mMZ" alt="" width="800" height="625"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fala Devs!&lt;/p&gt;

&lt;p&gt;Nesta semana lá na California rolou o evento anual da Google que ela apresenta seus principais lançamentos do ano chamado Google I/O.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NcuL_4Gi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AnRViprMa-oD6tRSj24uoSQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NcuL_4Gi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AnRViprMa-oD6tRSj24uoSQ.png" alt="" width="758" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na terça feira foi realizado o keynote principal, transmitido ao vivo em vários canais, e muitos ficaram decepcionados pois nada se falou sobre Flutter. Mas vou te contar um segredo, a Google não é uma empresa de desenvolvimento de software e nunca foi o foco da Google as ferramentas de desenvolvimento e em todos os Google I/O passados nunca foi falado de uma ferramenta de desenvolvimento no keynote principal, geralmente eles anunciam produtos que irão gerar receitas, como foi o caso nos anos passados do Google Glass, Pixel Fold, Stadia, versões do android e nesse ano, como IA é o assunto do momento e todas as empresas do mundo só fala nisso, o GEMINI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_ndOdVRx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AlZUGYnQ-Um78Bf3n8W8OcA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_ndOdVRx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AlZUGYnQ-Um78Bf3n8W8OcA.png" alt="" width="706" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mas calma jovem gafanhoto, disse que não teve Flutter apenas no Keynote de abertura/principal, passados algumas horas teve o keynote de abertura voltado ao desenvolvimento apresentando as novidades que irão rolar em TODOS os produtos google voltado a desenvolvedores como o Firebase que agora terá uma versão SQL, o KMP e brevemente falaram sobre o Flutter que agora na versão 3.22 está com o WebAssembly na stable e os MacrOS em experimental&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vLz5NXa7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AA4lcvO8S5nJPCOHO0gEADQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vLz5NXa7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AA4lcvO8S5nJPCOHO0gEADQ.png" alt="" width="714" height="978"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No dia seguinte (Quarta-feira) foi o dia que rolaram mais keynotes, daí sim, voltada a desenvolvedores e foram disponibilizadas online para que possamos assistir, confira em &lt;a href="https://io.google/2024/explore/?q=flutter"&gt;https://io.google/2024/explore/?q=flutter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E tivemos uma para mostrar as novidades do Flutter intitulada como “What is new in Flutter”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--18aOkClS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ASvFO5pi25inJx6ZpqYjbnw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--18aOkClS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ASvFO5pi25inJx6ZpqYjbnw.png" alt="" width="675" height="503"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nesse keynote apresentada por dois engenheiros da equipe do Flutter e Dart, o Kevin Moore e John Ryan eles apresentaram as novidades que vieram junto com o Flutter 3.22.0&lt;/p&gt;

&lt;p&gt;Primeiramente eles apresentaram os novos cases questão utilizando Flutter&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DA8X5KqK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AB_b-28LHTe-5o86oUDK8cw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DA8X5KqK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AB_b-28LHTe-5o86oUDK8cw.png" alt="" width="233" height="109"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Primeiramente falaram da Bricket que é um aplicativo para Android e iOS que usa IA para reconhecer LEGOS espalhados e com base nisso consegue dar várias ideias do que pode ser construído com os LEGOS disponíveis e ainda mostrará a localização exata de onde estão localizadas, eles ficaram bem animados com o poder do Flutter e já estão preparados para uma versão Web em menos de uma semana.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E_nmR_-a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/0%2AYP6ANiNAQHPENHcg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E_nmR_-a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/0%2AYP6ANiNAQHPENHcg.gif" alt="" width="499" height="1080"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A SuperCell, criadora de jogos como Hay Day, Clash of Clans, Boom Beach, Clash Royale, Brawl Stars e Squad Busters, decidiram utilizar o flutter na parte de gerenciamento de usuários e amigos e estão divididos em trocar todo o resto do aplicativo para flutter muito brevemente.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--N4oOGQJs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Avu9002-_kM9t_TxMynQBeQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--N4oOGQJs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Avu9002-_kM9t_TxMynQBeQ.png" alt="" width="541" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O Google Earth também tinha um problema de ter que manter varias stacks Android, iOS e web então ano passado decidiram migra-lo para utilizar Flutter pois dessa forma com um codebase só gerar aplicativos para Android, iOS e web tendo o mesmo comportamento.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hp2pnJdR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A0cYbSoinUloU_4wE7anKpA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hp2pnJdR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A0cYbSoinUloU_4wE7anKpA.png" alt="" width="720" height="188"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9cKnc-aU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AuFQi6sCAyHq-0s9xlht6Yw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9cKnc-aU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AuFQi6sCAyHq-0s9xlht6Yw.png" alt="" width="744" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jmWYzd75--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AefoWWoVTxW22BAaxa9Mo9A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jmWYzd75--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AefoWWoVTxW22BAaxa9Mo9A.png" alt="" width="330" height="180"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Também falaram da Universal e da LG que decidiram utilizar Flutter e com isso Ryan e Moore afimaram que Flutter se tornou o framework cross-platform mais popular do mundo&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0gary02w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AViBUnrEiJdWXxe7GWS633g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0gary02w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AViBUnrEiJdWXxe7GWS633g.png" alt="" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bom até agora só falamos de novos adeptos ao Flutter mas e as novidades? Vamos começar a falar&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eD7-wFgs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AQLyxqZ2Ctpn_dfxi94NwUw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eD7-wFgs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AQLyxqZ2Ctpn_dfxi94NwUw.gif" alt="" width="360" height="199"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Os 5 pilares
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--paNH-qmZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A7LcsHlIdirscUbdPaca7DQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--paNH-qmZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A7LcsHlIdirscUbdPaca7DQ.png" alt="" width="800" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nesta apresentação foi destacado os cinco pilares do Flutter e que qualquer alteração no Flutter será pautada em ao menos um desses cincos pilares: portabilidade, beleza, velocidade, produtividade e open source.&lt;/p&gt;

&lt;h3&gt;
  
  
  Portabilidade
&lt;/h3&gt;

&lt;p&gt;Toda e qualquer decisão do Flutter deve permitir que os desenvolvedores possam escrever código que pode ser executado em várias plataformas, como iOS, Android, web, Windows, macOS e Linux.&lt;/p&gt;

&lt;h3&gt;
  
  
  Beleza
&lt;/h3&gt;

&lt;p&gt;O Flutter fornece uma maneira de criar interfaces de utilizador atraentes e de alta qualidade.&lt;/p&gt;

&lt;h3&gt;
  
  
  Velocidade
&lt;/h3&gt;

&lt;p&gt;O Flutter é conhecido por sua rápida performance e renderização, o que permite aos desenvolvedores criar aplicações responsivas e performáticas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Produtividade
&lt;/h3&gt;

&lt;p&gt;O Flutter dispõe uma gama de recursos de auxiliam a produtividade, como hot-reload que permitem aos desenvolvedores ver as mudanças de código em tempo real e o DevTools&lt;/p&gt;

&lt;h3&gt;
  
  
  Open-Source
&lt;/h3&gt;

&lt;p&gt;O Flutter é um projeto de código aberto, o que significa que os desenvolvedores podem contribuir para o projeto e usar recursos de uma vasta comunidade de desenvolvedores.&lt;/p&gt;

&lt;h3&gt;
  
  
  GEMINI
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7C6M3MkP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ALZ-7_eTgSZSOWu-5fGJZxA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7C6M3MkP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ALZ-7_eTgSZSOWu-5fGJZxA.png" alt="" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sei que é um assunto que alguns já devem estar cansados, mas o fato é que a inteligência artificial é o assunto do momento e a Google está investindo pesado na sua nova ferramenta baseada em Large Language Model (LLM).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--G94mvoba--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AJdUFVoOAcesy7w1YDRQn2g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--G94mvoba--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AJdUFVoOAcesy7w1YDRQn2g.png" alt="" width="538" height="672"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O Flutter não poderia ficar pra trás e agora com o Google AI Dart SDK é possível integrar facilmente seus aplicativos Flutter com qualquer um dos modelos de IA generativa da Google, incluindo o Gemini. Já escrevi sobre ele por aqui (&lt;a href="https://medium.com/brasilflutter/oficial-gemini-google-ai-dart-flutter-sdk-integrando-flutter-com-o-gemini-90c46f8c2f7a"&gt;https://medium.com/brasilflutter/oficial-gemini-google-ai-dart-flutter-sdk-integrando-flutter-com-o-gemini-90c46f8c2f7a&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Para adicionar em seu projeto basta executar&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oe9VehNZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A1IKUbK_nTv7SvWQTphou1g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oe9VehNZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A1IKUbK_nTv7SvWQTphou1g.png" alt="" width="800" height="67"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E a utilização em código fica muito simples também&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J-zsKQh5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Avz51MUJ49c5ZUf06yNmydA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J-zsKQh5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Avz51MUJ49c5ZUf06yNmydA.png" alt="" width="800" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E seguindo os pilares do Flutter ele entra muito em sinergia com dois pilares Portabilidade, pois você pode utilizar o poder do Gemini codando apenas uma vez e rodando em qualquer lugar, e o pilar de Produtividade porque com o Google Generative AI conseguirá fazer a integração com GEMINI de forma muito simples e muito rápido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FoCYs_Pv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AXJ4rdQs78zpyG9icLOatZg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FoCYs_Pv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AXJ4rdQs78zpyG9icLOatZg.png" alt="" width="541" height="181"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para maiores informações acesse &lt;a href="https://flutter.dev/ai"&gt;https://flutter.dev/ai&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Games
&lt;/h3&gt;

&lt;p&gt;O Flutter é ótimo para o desenvolvimento de aplicativos, mas a equipe do Flutter vem investindo muito também no desenvolvimento de jogos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bKTyKXA4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AgflXs3rQ8Akd5jAgSVlypA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bKTyKXA4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AgflXs3rQ8Akd5jAgSVlypA.png" alt="" width="800" height="677"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A arquitetura do Flutter, embora robusta e flexível, permite a criação de camadas com acesso a níveis inferiores. Essa flexibilidade possibilita o desenvolvimento de uma engine que facilita a interoperabilidade entre diferentes componentes e sistemas.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhxozjgqz4wz7kkl57f8z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhxozjgqz4wz7kkl57f8z.png" alt="Image description" width="305" height="241"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E foi exatamente isso que o pessoal do Flame que é engine para jogos 2D que utiliza Dart e Flutter mantida por uma comunidade open-source, disponibilizando uma API de desenvolvimento alto nível para jogos&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5YUmHvFK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AQMci68eZvFjLUEFOQT1sPQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5YUmHvFK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AQMci68eZvFjLUEFOQT1sPQ.png" alt="" width="800" height="637"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E com ele podemos fazer jogos muito divertidos como o exemplo abaixo&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SfXEDTjj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AiUdcGYe-0W6Z1OH3rE5hvQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SfXEDTjj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AiUdcGYe-0W6Z1OH3rE5hvQ.gif" alt="" width="502" height="737"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com Flame conseguimos inicializar a construção de um jogo utilizando os conceitos primeiros de um jogo, como game loop, física e detecção de colisão 2D.&lt;/p&gt;

&lt;p&gt;E com a novo suporte ao DevTools Extensions lançada ano passado no flutter 3.16 a galerinha do Flame também fizeram sua extensão ao DevTools onde nos possibilita pausar o game loop, executar frame a frame e inspecionar os elementos na tela&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5NL6dTmU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Ajpu7dRI5n47yib7giVx9ww.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5NL6dTmU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Ajpu7dRI5n47yib7giVx9ww.gif" alt="" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E desde ano passado a equipe do Flutter tem investindo bastante no Casual Games Toolkit e ele está disponível para testar no DartPad.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_RNEX3_8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AhJljKU-P3PkD5l-St_TGEg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_RNEX3_8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AhJljKU-P3PkD5l-St_TGEg.png" alt="" width="800" height="746"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E essa questão dos jogos está muito em acordo com os cinco pilares do Flutter&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Q0pe2A5W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AbDpByOQM3m_3Z8dgM7501Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Q0pe2A5W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AbDpByOQM3m_3Z8dgM7501Q.png" alt="" width="541" height="181"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para saber mais acesse &lt;a href="https://flutter.dev/games"&gt;https://flutter.dev/games&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Impeller
&lt;/h3&gt;

&lt;p&gt;Já tínhamos ouvido falar do impeller, o novo renderizador gráfico, ano passado na ultima versão do Flutter 3.16 que já estava disponível para o iOS, agora na versão 3.22 também está disponível para Android.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wmbzRoTV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AK0pPKA-VBU3XLBVAEwqsww.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wmbzRoTV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AK0pPKA-VBU3XLBVAEwqsww.gif" alt="" width="800" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Atualmente o Flutter usa o Skia como motor de renderização para desenhar várias operações complexas compilando em um shader para executar em sua GPU, isso causa uma grande sensação de performance, entretanto pode causar algumas perdas de frames na primeira compilação quando temos muitos widgets na tela, como o exemplo acima.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZEpoXtFw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AVacR9-eyD9w_StL_vqDAYw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZEpoXtFw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AVacR9-eyD9w_StL_vqDAYw.gif" alt="" width="283" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para isso a equipe do Flutter reescreveu o motor de renderização trazendo uma melhor performance para seus aplicativos. O Impeller foi projetado para ser mais rápido e eficiente do que o motor de renderização original do Flutter, “Skia”. Isso é especialmente útil para aplicações com muitos widgets e animações complexas, onde a performance é crucial para uma experiência suave. Uma das melhorias que já podemos notar é a renderização de efeito de desfoque no iOS chegando a ser duas vezes mais rápido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wIVwqdZN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ABsHfGYIVITAuE647ac3uGQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wIVwqdZN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ABsHfGYIVITAuE647ac3uGQ.gif" alt="" width="283" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para utilizarmos o impeller adicione a flag &lt;strong&gt;— — enable-impeler&lt;/strong&gt; no &lt;strong&gt;flutter run&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RjDySgFQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AyGBrtuBLY5_IngWBxz7Mkw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RjDySgFQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AyGBrtuBLY5_IngWBxz7Mkw.png" alt="" width="800" height="88"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para maiores informações acesse &lt;a href="https://docs.flutter.dev/perf/impeller"&gt;https://docs.flutter.dev/perf/impeller&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O impeller fica muito alinhado com o pilar de portabilidade e velocidade por trazer mais portabilidade (agora o android em stable) e trazer mais performance em seus aplicativos&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HDuv0ZVX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ATUC8j3OD85Jn6REMMmsOPA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HDuv0ZVX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ATUC8j3OD85Jn6REMMmsOPA.png" alt="" width="800" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Macros&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Agora a estrela do dia que todos estavam esperando com toda certeza foi as Macros que na versão 3.22 foi anunciado que está na fase de experimental, isso significa que logo chegará a stable (a Google tem planos de ainda lançar este ano), como sabemos o Dart do Flutter não temos a famosa reflection e o Dart do Flutter é capado e não temos acesso aos Mirrors, fazendo com que não seja possível a meta-programação e fiquemos reféns do odiado build_runner.&lt;/p&gt;

&lt;p&gt;E por muito tempo os Devs flutter solicitavam a equipe do Flutter coisas simples, como deserializaçao de JSON e Data Class nativa no Dart para que não precisássemos fazer na mão ou utilizar package terceiros.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZaNGxqM5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Ah4mQ60SB8Z3bn85B-nU5lw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZaNGxqM5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Ah4mQ60SB8Z3bn85B-nU5lw.png" alt="" width="800" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao contrario do que imaginamos a equipe do Flutter ouvia essas solicitações entretanto implementar esses metodos acima sem o auxilio de reflections ou geraçao de codigo não é tao simples e geravam muitos problemas.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QFdtlsId--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AZL8VcPPBh9ex0kKYLo_rLA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QFdtlsId--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AZL8VcPPBh9ex0kKYLo_rLA.png" alt="" width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Então a solução infelizmente era, desenvolver esses métodos na mão ou utilizar um package terceiro que iria gerar esse código com o auxílio do build_runner. Ambas as soluções deixavam o desenvolvimento lento e inflexível.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qTj3D6LT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AgmtLcwfwdMXj-5luXArMiQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qTj3D6LT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AgmtLcwfwdMXj-5luXArMiQ.png" alt="" width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Então a solução que a Google está desenvolvendo para resolver este problema são as Macros que foi oficialmente lançado agora na fase experimental, que veio para nos auxiliares na meta programação.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I4A16wBy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AKe3F2AcNwfEDQ9vxrJDDtA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I4A16wBy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AKe3F2AcNwfEDQ9vxrJDDtA.gif" alt="" width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para mais informações acesse &lt;a href="https://dart.dev/language/macros"&gt;https://dart.dev/language/macros&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com isso continuamos alinhados com os pilares do flutter.&lt;/p&gt;

&lt;p&gt;Melhor produtividade: As macros podem ajudar os desenvolvedores a escrever código mais rápido e conciso, reduzindo a quantidade de código repetitivo.&lt;/p&gt;

&lt;p&gt;Performance: As macros podem otimizar o código Dart para um melhor desempenho, especialmente em cenários de alta demanda, como desenvolvimento de jogos.&lt;/p&gt;

&lt;p&gt;Open source: você pode personalizar a definição como as “Data Classes” usando macros. Isso permite um controle preciso sobre o comportamento e os dados que sua classe de dados gerencia.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CwzKlNU8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ARb34542dsqyX6sogD9YE3Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CwzKlNU8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ARb34542dsqyX6sogD9YE3Q.png" alt="" width="800" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Web Assembly
&lt;/h3&gt;

&lt;p&gt;No Google I/O foi finalmente lançado o WebAssembly para Flutter Web e foi demonstrado como uma tecnologia que está expandindo os horizontes do Flutter para a web, abrindo novas possibilidades para performance e complexidade de aplicações web. O WebAssembly permite que aplicações Flutter para a web renderizem gráficos complexos com alta qualidade e performance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---XRAyuRW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Ai1HpN1Gml5SKckWV_blF_g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---XRAyuRW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Ai1HpN1Gml5SKckWV_blF_g.png" alt="" width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Os pontos principais sobre WebAssembly foram:&lt;/p&gt;

&lt;p&gt;Performance: O WebAssembly permite que código compilado, como o código Dart do Flutter, seja executado em navegadores web com uma performance muito mais próxima do código nativo. Isso significa que aplicações Flutter para a web podem ser tão rápidas e eficientes quanto aplicações nativas.&lt;/p&gt;

&lt;p&gt;Extensão do Ecossistema: O WebAssembly permite integrar bibliotecas de código nativo (C, C++, Rust) em aplicações web, aumentando a capacidade de lidar com tarefas complexas que antes eram limitadas a aplicações nativas.&lt;/p&gt;

&lt;p&gt;Novo Nível de Interatividade: Com o WebAssembly, aplicações web podem ter um nível de interatividade e complexidade antes restrito a aplicações nativas. Isso abre portas para aplicações web mais avançadas, como jogos complexos e aplicações com gráficos intensivos.&lt;/p&gt;

&lt;p&gt;Fazendo um benchmark com um código e gerando para Android, Web (utilizando o motor de JS) e com o Wasm teremos o dobro de performance com Wasm em relação de como utilizamos o flutter web hoje.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ljGU1jx9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Aacy_AWUKA74mBFvxb1LWNw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ljGU1jx9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Aacy_AWUKA74mBFvxb1LWNw.png" alt="" width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0YO05Jpm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/0%2A7yWujA-ZPvZqQtk9" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0YO05Jpm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/0%2A7yWujA-ZPvZqQtk9" alt="" width="719" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O WebAssembly é um componente fundamental para o futuro do Flutter na web, permitindo que a plataforma alcance um nível de performance e complexidade que antes era inimaginável e irá revolucionar a forma como as aplicações Flutter são construídas para a web. Uma tecnologia promissora que abre novas possibilidades para o desenvolvimento web com o Flutter. Essa tecnologia permite que aplicações web Flutter alcancem performance próxima do código nativo e integrem bibliotecas nativas, tornando-as mais complexas e interativas. Estando completamente alinhados com os pilares do flutter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y423kULu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AyYLDMx7J58SeMZ57Gvt8Tw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y423kULu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AyYLDMx7J58SeMZ57Gvt8Tw.png" alt="" width="800" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para mais informações acesse &lt;a href="https://flutter.dev/wasm"&gt;https://flutter.dev/wasm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bom então resumindo tivemos 5 grandes atualizações que causam impactos enormes para nosso desenvolvimento&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XIlMUEmf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AMJ4VxNX-wgt05bHKr5gKyw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XIlMUEmf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AMJ4VxNX-wgt05bHKr5gKyw.png" alt="" width="800" height="617"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Não foram muitas novidades, em questão de quantidade, mas o impacto que essas pequenas melhorias vão causar é inimaginável.&lt;/p&gt;

&lt;p&gt;Aguardemos as próximas atualizações&lt;/p&gt;

&lt;p&gt;Confira a talk na integra&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/flutter/whats-new-in-flutter-3-22-fbde6c164fe3"&gt;&lt;strong&gt;What’s new in Flutter 3.22&lt;/strong&gt;&lt;/a&gt;&lt;a href="https://medium.com/flutter/whats-new-in-flutter-3-22-fbde6c164fe3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--08iEc3Pu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A12QvPBZZuDYn_fk5raBGNA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--08iEc3Pu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A12QvPBZZuDYn_fk5raBGNA.png" alt="" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Entre em nosso discord para interagir com a comunidade e ficar por dentro de todas as nossas publicações: flutterbrasil.com.br&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>googleio</category>
      <category>dart</category>
    </item>
    <item>
      <title>Desenhos complexos com CustomPaint</title>
      <dc:creator>Toshi Ossada</dc:creator>
      <pubDate>Sat, 18 May 2024 14:04:20 +0000</pubDate>
      <link>https://dev.to/flutterbrasil/desenhos-complexos-com-custompaint-3hd5</link>
      <guid>https://dev.to/flutterbrasil/desenhos-complexos-com-custompaint-3hd5</guid>
      <description>&lt;p&gt;No ultimo artigo vimos os conceitos básicos do CustomPaint e como ele pode nos habilitar a desenhar qualquer forma geométrica no Flutter, agora vamos juntar essas formas geométricas para que possamos fazer desenhos mais complexos.&lt;/p&gt;

&lt;p&gt;Por exemplo, se juntarmos arco com linhas podemos desenhar um relógio&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NgvVGegk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A7iIRu7lkzsGqhE8fFJ_65w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NgvVGegk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A7iIRu7lkzsGqhE8fFJ_65w.png" alt="" width="448" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Primeiramente vamos desenhar o arco do relógio&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JNDIAZb6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A4NC6Mu6X-9gD7tKFTrIieQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JNDIAZb6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A4NC6Mu6X-9gD7tKFTrIieQ.png" alt="" width="413" height="400"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;O arco vai de 0 à 2pi para formar uma circunferência completa&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qDG9rVmZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AjLpVFNFk60X_Ou-ph8dfbA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qDG9rVmZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AjLpVFNFk60X_Ou-ph8dfbA.png" alt="" width="270" height="198"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora precisamos gerar 12 linhas que irá representar as 12 horas do nosso relógio e precisamos posiciona-los no ângulo exato de cada hora, para isso pegamos o valor de 2pi e dividimos por 12 e depois multiplicamos pela hora.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZU4wXazQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Aw6pGjArdkmmd_1Zwn0Fe3A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZU4wXazQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Aw6pGjArdkmmd_1Zwn0Fe3A.png" alt="" width="764" height="552"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Agora iremos desenhar os ponteiros do nosso relógio, para isso precisamos saber como converter horas e minutos em ângulos para isso utilizarei o &lt;a href="https://gemini.google.com/"&gt;https://gemini.google.com/&lt;/a&gt; para me ajudar a desenvolver meu método.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--L-ONwo7l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Aum5f4zY8SBV40hISfXHOxg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--L-ONwo7l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Aum5f4zY8SBV40hISfXHOxg.png" alt="" width="800" height="142"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E cheguei nessa função&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Com a função de converssao de horas em angulo basta desenharmos duas linhas passando o sem e cos do ângulo&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U3VxGGuL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Age1VoS_3CAVJQ0fmWLszsQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U3VxGGuL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Age1VoS_3CAVJQ0fmWLszsQ.png" alt="" width="800" height="615"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JD7vTyqQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A6VUTqYPd6gr7RvD3K75Lhg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JD7vTyqQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A6VUTqYPd6gr7RvD3K75Lhg.png" alt="" width="464" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E para finalizar vamos colocar um circulo no centro para representar a junção dos ponteiros&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KuBybDLY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A681XLjMQxXS0jZOu3P--vQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KuBybDLY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A681XLjMQxXS0jZOu3P--vQ.png" alt="" width="797" height="59"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E o resultado será este:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7XUYCRgA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AyEK00pigaeh9rziDJNI94g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7XUYCRgA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AyEK00pigaeh9rziDJNI94g.png" alt="" width="441" height="522"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E de bônus vamos aprender a fazer aquelas mascara na câmara quando queremos enquadrada algo (como o rosto)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VXSL9vxx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AiSZi6BOdTzrVOQxFVAkubQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VXSL9vxx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AiSZi6BOdTzrVOQxFVAkubQ.png" alt="" width="531" height="998"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Primeiramente vamos instalar algum package de câmera, estou utilizando o câmera&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SMykBB4u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AAuHKVd12o-dsP7VY3AfeuA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SMykBB4u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AAuHKVd12o-dsP7VY3AfeuA.png" alt="" width="331" height="116"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E vamos inicializa-la em nosso widget&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZD4A2aS9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A4upPoZKpNYIdsJbe31cE4Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZD4A2aS9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A4upPoZKpNYIdsJbe31cE4Q.png" alt="" width="800" height="935"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A construção do nosso widget será a seguinte, uma Stack onde o primeiro item de nossa Stack será a câmera e o segundo item será nosso custom paint que ficará acima da câmera.&lt;/p&gt;

&lt;p&gt;E com isso iremos criar um Retangulo que irá cobrir nossa camera.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KimpiWVa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A_ylpn14bNGfj35bM8E4iLw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KimpiWVa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A_ylpn14bNGfj35bM8E4iLw.png" alt="" width="792" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4aWJbfrW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AGE4nRGx7AJCNvT0Jg6dYug.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4aWJbfrW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AGE4nRGx7AJCNvT0Jg6dYug.png" alt="" width="527" height="995"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora vamos desenhar um circulo oval que será o local que iremos centralizar o rosto na câmera&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9aW79OSB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AaShV-eCTtNqGXiafw9QMfw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9aW79OSB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AaShV-eCTtNqGXiafw9QMfw.png" alt="" width="794" height="606"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O resultado será um circulo preto no meio da tela&lt;/p&gt;

&lt;p&gt;Com o path é possível fazer algumas operações como retirar a diferença entre dois paths, com isso podemos fazer um recorte em nosso CustomPaint criando um buraco na tela.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RCGWvCBC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Agd9PzXLl0EnSSrTIr4xy4Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RCGWvCBC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Agd9PzXLl0EnSSrTIr4xy4Q.png" alt="" width="536" height="1003"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com o path é possível fazer algumas operações como retirar a diferença entre dois paths, com isso podemos fazer um recorte em nosso CustomPaint criando um buraco na tela.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yNX1ZV9i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A8mtHTFRqOgAfM-42EoUfEA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yNX1ZV9i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A8mtHTFRqOgAfM-42EoUfEA.png" alt="" width="800" height="560"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E voilá temos, temos nossa mascara para o rosto.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--36he16Ig--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AkYeu-kwpVCeiY-ipJnBJ_Q.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--36he16Ig--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AkYeu-kwpVCeiY-ipJnBJ_Q.gif" alt="" width="318" height="650"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Você pode acessar esses dois exemplo em meu github&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/toshiossada/clippath"&gt;https://github.com/toshiossada/clippath&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Legal né? Lembrando que poderíamos ter usado este recurso com um Socket, como o Firebase para que a ativação e desativação seja de forma instantânea, caso seu negócio necessite&lt;/p&gt;

&lt;p&gt;Confira o exemplo completo em&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/toshiossada/togglefeature"&gt;https://github.com/toshiossada/togglefeature&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F5SS5ANk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/0%2AFPHz4rb0uv3Fq5OQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F5SS5ANk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/0%2AFPHz4rb0uv3Fq5OQ.png" alt="" width="800" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Entre em nosso discord para interagir com a comunidade: &lt;a href="https://discord.com/invite/flutterbrasil"&gt;https://discord.com/invite/flutterbrasil&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://linktr.ee/flutterbrasil"&gt;https://linktr.ee/flutterbrasil&lt;/a&gt;&lt;/p&gt;

</description>
      <category>custom</category>
      <category>paint</category>
      <category>complex</category>
      <category>draw</category>
    </item>
    <item>
      <title>Oficial! Gemini Google AI Dart/Flutter SDK— Integrando Flutter com o GEMINI</title>
      <dc:creator>Toshi Ossada</dc:creator>
      <pubDate>Sat, 18 May 2024 13:58:49 +0000</pubDate>
      <link>https://dev.to/flutterbrasil/oficial-gemini-google-ai-dartflutter-sdk-integrando-flutter-com-o-gemini-29ka</link>
      <guid>https://dev.to/flutterbrasil/oficial-gemini-google-ai-dartflutter-sdk-integrando-flutter-com-o-gemini-29ka</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XjBV5d9y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A3gmetTYfX_C4Y_THLmXUZQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XjBV5d9y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A3gmetTYfX_C4Y_THLmXUZQ.png" alt="" width="716" height="237"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fala Devs, blz?&lt;/p&gt;

&lt;p&gt;No dia 14/02/2024 a Google anunciou oficialmente o Gemini(&lt;a href="https://gemini.google.com/"&gt;https://gemini.google.com/&lt;/a&gt;) e no dia 15/02/2024 a Google nos surpreendeu com o lançamento do Flutter 3.19.0 e com ele o Dart 3.3 essa versão veio com muitas novidades (&lt;a href="https://medium.com/flutter/whats-new-in-flutter-3-19-58b1aae242d2"&gt;https://medium.com/flutter/whats-new-in-flutter-3-19-58b1aae242d2&lt;/a&gt;) que iremos comentar em breve. Contudo, algo que nos fez brilhar os olhos foi o anúncio do Gemini google AI Dart SDK, ou seja, um SDK do Gemini nativamente para o Flutter/Dart, isso ressalta a importância que o Flutter está tendo para a Google, pois o Flutter/DART é a primeira ferramenta com um SDK Nativo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7VVRytOg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AZY5DDMWq9a--zHBcCR2fNw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7VVRytOg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AZY5DDMWq9a--zHBcCR2fNw.png" alt="" width="800" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E eu vendo isso já fui testar e trazer as novidade para vocês, pois com um package desenvolvido pela Google faz perder todo o sentido de usar um pacote terceiro para podermos integrar com o Gemini(&lt;a href="https://pub.dev/packages/google_generative_ai"&gt;https://pub.dev/packages/google_generative_ai&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Para começar ainda necessitaremos gerar nossa API Key em &lt;a href="https://ai.google.dev/"&gt;https://ai.google.dev/&lt;/a&gt; como expliquei em detalhes no artigo anterior.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--moTX50YF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AkEH8hM2twCcs9wvckqvusw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--moTX50YF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AkEH8hM2twCcs9wvckqvusw.png" alt="" width="800" height="649"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora em nosso projeto flutter necessitaremos adicionar o pacote no pubspec&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;flutter pub add google_generative_ai&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Iremos abordar os dois modos disponíveis: somente texto e chat com contexto. Para configurar o Gemini precisamos instanciar o objeto GenerativeModel() passando a ApiKey (que estamos passando via dart-define-from-file) e o modelo de IA, iremos utilizar o gemini-pro.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Para gerarmos um diálogo com o Gemini precisamos gerar um Content.text(String) passando nossa pergunta e utilizando o método generateContent() do GeminiModel() iremos obter a resposta dada pela IA.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;E a partir daí é só mostrar na tela a resposta gerada pelo Gemini, caso deseja fazer a animação de digitação igual ao artigo anterior podemos utilizar o AnimatedTextKit(&lt;a href="https://pub.dev/packages/animated_text_kit"&gt;https://pub.dev/packages/animated_text_kit&lt;/a&gt;) para isso.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6egS-Ske--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AU1qsn4FGhg-qhBEOa05mFA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6egS-Ske--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AU1qsn4FGhg-qhBEOa05mFA.gif" alt="" width="587" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Também é possível criar um diálogo com contexto para a conversa, podendo pré-definir algum prompt, para isso precisamos além de configurar o GeminiModel() também necessitamos iniciar um chat com o método startChat()&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Agora para enviar mensagens para o Gemini basta executarmos o método sendMessage() passando a mensagem.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Agora para mostrarmos a conversa a tela podemos pegar o histórico do chat&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;O history nos traz algumas informações importante com o remetente da mensagem no atributo role que será “user” caso tenha sido o usuário que enviou a mensagem ou “model” caso seja a IA que tenha enviado a mensagem.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TLYo3lJ9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A3FZDP0M-by18hgYvXu0pJA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TLYo3lJ9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A3FZDP0M-by18hgYvXu0pJA.png" alt="" width="586" height="163"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Outro ponto importante é juntar todas as partes da resposta enviada pelo Gemini&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PrwjrOfi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Aqmkiiw9OEuWy4ssiJ0XL5A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PrwjrOfi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Aqmkiiw9OEuWy4ssiJ0XL5A.png" alt="" width="491" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E por fim podemos exibir a mensagem na tela do nosso aplicativo&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aZdsM9TU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ApwvHBTLAOPnwsF5IRcWuiQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aZdsM9TU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ApwvHBTLAOPnwsF5IRcWuiQ.png" alt="" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E o resultado será esse&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3yzJKYwa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Ad--kK-IWIffqlsTfVWGLWA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3yzJKYwa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Ad--kK-IWIffqlsTfVWGLWA.gif" alt="" width="587" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Infelizmente o modelo de análise de imagens ainda não esta disponivel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H7OaG0uR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A09t2vi062DjdYTF20W-ORw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H7OaG0uR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A09t2vi062DjdYTF20W-ORw.png" alt="" width="619" height="31"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mas creio que em um futuro proxímo poderemos fazer algo do tipo&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Vale ressaltar que alguns recursos não estão disponíveis na versão gratuita e é possível consultar os planos em &lt;a href="https://ai.google.dev/pricing?hl=pt-br"&gt;https://ai.google.dev/pricing?hl=pt-br&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X2cJF09i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AgF1K1ZrGHRe0osnT3yYUFQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X2cJF09i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AgF1K1ZrGHRe0osnT3yYUFQ.png" alt="" width="800" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Muito bacana essa novidade né? Todos sabemos que o Gemini é a grande novidade da Google e que eles vão investir e evoluir muito nele e que em menos de uma semana já desenvolveram um SDK para o Flutter só nos mostra a importância desta ferramenta que amamos para a Google e que ainda tem muitos anos de vida.&lt;/p&gt;

&lt;p&gt;Podem conferir o exemplo que usei neste artigo em&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/toshiossada/gemini_flutter_example"&gt;https://github.com/toshiossada/gemini_flutter_example&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Entre em nosso discord para interagir com a comunidade: flutterbrasil.com.br&lt;/p&gt;

</description>
      <category>gemini</category>
      <category>llm</category>
      <category>ia</category>
      <category>flutter</category>
    </item>
    <item>
      <title>Desenhe o que quiser com Custom Paint no Flutter</title>
      <dc:creator>Toshi Ossada</dc:creator>
      <pubDate>Sat, 18 May 2024 13:51:21 +0000</pubDate>
      <link>https://dev.to/flutterbrasil/desenhe-o-que-quiser-com-custom-paint-no-flutter-1kdo</link>
      <guid>https://dev.to/flutterbrasil/desenhe-o-que-quiser-com-custom-paint-no-flutter-1kdo</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AHwzkvQYd6V_QWcTyra2aQQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AHwzkvQYd6V_QWcTyra2aQQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fala Devs,&lt;/p&gt;

&lt;p&gt;Que o &lt;strong&gt;Flutter&lt;/strong&gt; é uma poderosa ferramenta que nos traz uma gama de widgets, possibilitando a criação de layouts modernos e bonitos, isso já sabemos. Mas sabia que o Flutter também possui uma ferramenta muito legal que nos permite ter uma variedade de efeitos visuais, desde formas geométricas simples como linha, quadrado, arco, círculo, etc., até desenhos complexos e animados? Literalmente, podemos desenhar com código em nossos widgets. Estou falando do &lt;strong&gt;CustomPaint&lt;/strong&gt;.&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=kp14Y4uHpHs" rel="noopener noreferrer"&gt;&lt;br&gt;
 &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.youtube.com%2Fvi%2Fkp14Y4uHpHs%2F0.jpg" alt="Monorepo (Por Que Essa Estratégia Funciona em Grandes Empresas?) "&gt;&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Como funciona?
&lt;/h3&gt;

&lt;p&gt;Para começarmos a utilizá-lo é muito simples, basta usarmos um widget chamado &lt;strong&gt;CustomPaint()&lt;/strong&gt;, e ele espera que passemos como parâmetro um &lt;strong&gt;CustomPainter&lt;/strong&gt; e o tamanho que nosso painter terá.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Nosso &lt;strong&gt;painter&lt;/strong&gt; será uma classe que irá estender a classe &lt;strong&gt;CustomPainter&lt;/strong&gt; e terá dois métodos principais. Um será o &lt;strong&gt;shouldRepaint()&lt;/strong&gt;, que será o método responsável pela lógica que determina se nosso painter deve ser redesenhado ou não, semelhante ao &lt;strong&gt;didUpdateWidget(&lt;/strong&gt;) de um &lt;strong&gt;StatefulWidget&lt;/strong&gt;. Por hora, podemos retornar sempre &lt;strong&gt;true&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;O segundo método, que é o mais importante, é o &lt;strong&gt;paint()&lt;/strong&gt;. Aqui é onde colocaremos todas as instruções do que queremos desenhar. Neste método, temos dois parâmetros importantes: o &lt;strong&gt;Size&lt;/strong&gt;, que é a informação do tamanho da área que teremos para realizar nosso desenho, e o &lt;strong&gt;Canvas&lt;/strong&gt;, que é responsável por realizar o desenho dentro do nosso ‘quadro’.&lt;/p&gt;

&lt;p&gt;Neste exemplo criamos o &lt;strong&gt;Paint()&lt;/strong&gt;, que é o responsável por conter todas as informações da propriedade do nosso desenho (Cor, espessura de linha, etc), no caso colocamos a cor roxa e com o estilo preenchido, isso significa que quando ele fechar todos os pontos de do desenho ele irá preencher com a cor selecionada. E por fim utilizamos o &lt;strong&gt;Rect.fromLTWH()&lt;/strong&gt; que irá desenha um retângulo a partir dos pontos de par ordenado (lembra das aulas de matemática?) que passamos, lembrando que o ponto inicial é o [0, 0] e ele vai até ponto [&lt;strong&gt;largura_maxima, altura_maxima&lt;/strong&gt;]. Por fim utilizando o &lt;strong&gt;Canvas&lt;/strong&gt; simplesmente mando ele desenhar no meu painter utilizando o método &lt;strong&gt;drawRect()&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;Também temos a opção de passar o &lt;strong&gt;style&lt;/strong&gt; como &lt;strong&gt;stroke&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;Desta forma ele não preencherá o interior do desenho&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Linhas
&lt;/h3&gt;

&lt;p&gt;Também podemos desenhar linhas, basta utilizarmos a classe &lt;strong&gt;Path()&lt;/strong&gt; para informar os pontos de ligação das linhas. Primeiramente, usamos o &lt;strong&gt;moveTo(0, 0)&lt;/strong&gt; para informar o ponto inicial do desenho, e em seguida, utilizamos o &lt;strong&gt;lineTo()&lt;/strong&gt; para informar o par ordenado dos pontos de ligação das linhas. Por fim, instruímos o canvas a desenhar nossos Paths utilizando o &lt;strong&gt;drawPath()&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Como resultado teremos&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Curvas
&lt;/h3&gt;

&lt;p&gt;Ainda utilizando os Paths também conseguimos fazer curvas, a primeira forma é utilizado o &lt;strong&gt;quadraticBezierTo&lt;/strong&gt; ele adiciona um ponto “invisível” que vai flexionar a linha naquela direção.&lt;/p&gt;

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

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

&lt;p&gt;Também temos o &lt;strong&gt;cubicTo&lt;/strong&gt; que diferente do &lt;strong&gt;quadraticBezierTo&lt;/strong&gt; ele adiciona dois pontos de flexão.&lt;/p&gt;

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

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

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

&lt;p&gt;No &lt;strong&gt;CustomPainter&lt;/strong&gt; também conseguimos usar em conjunto com o &lt;strong&gt;ClipPath&lt;/strong&gt;, suponhamos que temos 2 retângulos sobrepostos e queiramos fazer um recorte em um deles para quer aparecer os dois retângulos ocupando metade da tela com um corte personalizado&lt;/p&gt;

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

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

&lt;p&gt;Podemos adicionar o primeiro retângulo com o &lt;strong&gt;drawRect()&lt;/strong&gt; e em seguida utilizar o &lt;strong&gt;clipPath&lt;/strong&gt; do &lt;strong&gt;Canves&lt;/strong&gt; passando o &lt;strong&gt;Path&lt;/strong&gt; com as ordenadas do corte e logo em seguida adicionar o segundo retângulo.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
Como resultado teremos

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

&lt;h3&gt;
  
  
  Arcos
&lt;/h3&gt;

&lt;p&gt;Lembra das aulas de Geometria? Aqui utilizaremos os conceitos aprendidos, sabemos que um círculo inteiro possui &lt;strong&gt;2PI&lt;/strong&gt;, no &lt;strong&gt;Paint&lt;/strong&gt; e o ponto zero fica no meio do lado direito.&lt;/p&gt;

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

&lt;p&gt;E com isso conseguimos desenhar um círculo ou parte dele utilizando os conceitos de seno.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2ACDsdiWq8uhVNWeGflJx-Nw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2ACDsdiWq8uhVNWeGflJx-Nw.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
Com esses conceitos podemos fazer um progresso circular.

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

&lt;p&gt;Recebemos o progresso e o texto por parâmetro&lt;/p&gt;

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

&lt;p&gt;Em seguida utilizando o &lt;strong&gt;drawArc&lt;/strong&gt; passando o seno inicial &lt;strong&gt;3PI/2&lt;/strong&gt; (imagine esta imagem invertida)&lt;/p&gt;

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

&lt;p&gt;E passando o progresso como parâmetro para o &lt;strong&gt;drawArc&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;Também conseguimos pedir para o &lt;strong&gt;CustomPaint&lt;/strong&gt; desenhar textos, utilizando o TextSpan e depois assando a posição onde ele ficará&lt;/p&gt;

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

&lt;p&gt;Legal né? Da para fazer muita coisa com &lt;strong&gt;CustomPaint&lt;/strong&gt;, nos próximos artigos vamos trabalhar um pouco mais com eles.&lt;/p&gt;

&lt;p&gt;Os exemplos que utilizei no artigo se encotram no meu github :)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/toshiossada/clippath" rel="noopener noreferrer"&gt;https://github.com/toshiossada/clippath&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Entre em nosso discord para interagir com a comunidade: flutterbrasil.com.br&lt;/p&gt;

</description>
      <category>custom</category>
      <category>paint</category>
      <category>draw</category>
      <category>flutter</category>
    </item>
    <item>
      <title>Puro — Uma forma eficiente de gerenciar as versões flutter</title>
      <dc:creator>Toshi Ossada</dc:creator>
      <pubDate>Sat, 18 May 2024 13:45:42 +0000</pubDate>
      <link>https://dev.to/flutterbrasil/puro-uma-forma-eficiente-de-gerenciar-as-versoes-flutter-3d94</link>
      <guid>https://dev.to/flutterbrasil/puro-uma-forma-eficiente-de-gerenciar-as-versoes-flutter-3d94</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pnOn3kqC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ANG06IDt7z6kZdrN6Ff6yFQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pnOn3kqC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ANG06IDt7z6kZdrN6Ff6yFQ.png" alt="" width="257" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pode ser que você já tenha se deparado na situação de ter que trabalhar em vários projetos Flutter e que necessitam rodar em versões diferentes, infelizmente, isso é muito comum no mundo de desenvolvimento de software, por exemplo, recentemente tivemos o lançamento do flutter 3.13 que teve um pequeno &lt;strong&gt;Breaking Change&lt;/strong&gt;, por este motivo muitos projetos que estão na versão 3.10 não migraram para a versão estável e para o desenvolvedor que quer testar as novidades do Flutter tem que ficar alternando entre &lt;strong&gt;flutter downgrade&lt;/strong&gt; e &lt;strong&gt;flutter upgrade&lt;/strong&gt;, para isso são criados Gerenciadores de Versões, desta forma conseguimos deixar configurados qual versão do Flutter cada projeto irá utilizar.&lt;/p&gt;

&lt;p&gt;Já falamos aqui sobre o  &lt;a href="https://blog.flutterando.com.br/%C3%A9-do-brasil-fvm-uma-forma-simples-de-gerenciar-as-vers%C3%B5es-do-flutter-6e0999ce8ad9"&gt;&lt;strong&gt;FVM&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;(Flutter Version Management)&lt;/strong&gt; que é um gerenciador criado por um brasileiro(Leo Farias, Google Developer Experts em Dart) e que utilizei por muitos anos.&lt;/p&gt;

&lt;p&gt;Recentemente foi lançado o &lt;a href="https://puro.dev/"&gt;&lt;strong&gt;Puro&lt;/strong&gt;&lt;/a&gt;  que é um Gerenciador de Versões que pareceu muito legal e com a instalação bem simples.&lt;/p&gt;

&lt;p&gt;No próprio site do Puro traz um gráfico fazendo um comparativo entre Setup e Tempo de Instalação do Puro com outras formas de se instalar o Flutter e ele mostra um ganho de mais de 50% (sempre desconfiem desses benchmarks).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wgaQ5hgM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AZiw656Wjaz8CUeTeNdgw9w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wgaQ5hgM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AZiw656Wjaz8CUeTeNdgw9w.png" alt="" width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Também mostra um comparativo de gasto de download e economia de espaço de disco.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--l_7frLnl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ACy3zSTKnhPCJlF4Rng7VkA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--l_7frLnl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ACy3zSTKnhPCJlF4Rng7VkA.png" alt="" width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Então vamos ver como fazemos para instalar e utilizá-lo.&lt;/p&gt;

&lt;p&gt;A primeira dependência que precisamos resolver (caso ainda não conheça deveria aprender) é a instalação do git em sua máquina que é bastante simples.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--emysQHaB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AO8nRk1MZf3Zr-N0cb-1kjQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--emysQHaB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AO8nRk1MZf3Zr-N0cb-1kjQ.png" alt="" width="800" height="69"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se você como eu é um usuário do Windows recomendo utilizar o &lt;a href="https://chocolatey.org/"&gt;chocolatey&lt;/a&gt; para instalação de pacotes dentro do Windows, para instalar o chocolatey basta executar o PowerShell como administrador.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--h8wNDSpf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AJiGrWpqny4Xu-yzqtcCXJQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--h8wNDSpf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AJiGrWpqny4Xu-yzqtcCXJQ.png" alt="" width="644" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E executar o comando:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString(‘&lt;a href="https://community.chocolatey.org/install.ps1')"&gt;https://community.chocolatey.org/install.ps1')&lt;/a&gt;)&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pKn8_nv0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AxhWy191H_vsvF4GKKalWxQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pKn8_nv0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AxhWy191H_vsvF4GKKalWxQ.png" alt="" width="800" height="107"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para confirmar execute &lt;strong&gt;choco -v&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DIeJdeOW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AVr_VXI23Z28AvN6Yu-2K9g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DIeJdeOW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AVr_VXI23Z28AvN6Yu-2K9g.png" alt="" width="800" height="160"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pronto o chocolatey está instalado! agora podemos simplesmente instalar o &lt;strong&gt;git&lt;/strong&gt; executando.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;choco install git&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;e depois confirme com &lt;strong&gt;Y&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_ayVG2UO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Apzes43vHdWVUd3vX3bUSsg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_ayVG2UO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Apzes43vHdWVUd3vX3bUSsg.png" alt="" width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reinicie o PowerShell e execute &lt;strong&gt;git -v&lt;/strong&gt; para confirmar a instalação.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z_QG7QMU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2As7N10j5-gUCek4l9f4jS7w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z_QG7QMU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2As7N10j5-gUCek4l9f4jS7w.png" alt="" width="527" height="56"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora para a instalação do Puro basta executarmos no PowerShell (&lt;strong&gt;desta vez não execute como administrador&lt;/strong&gt;) o comando:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Invoke-WebRequest -Uri “&lt;a href="https://puro.dev/builds/1.3.5/windows-x64/puro.exe"&gt;https://puro.dev/builds/1.3.5/windows-x64/puro.exe&lt;/a&gt;" -OutFile “$env:temp\puro.exe”; &amp;amp;”$env:temp\puro.exe” install-puro –promote&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kPYEGyLG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A5lN_A_89YGv1pcqSDauLbQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kPYEGyLG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A5lN_A_89YGv1pcqSDauLbQ.png" alt="" width="800" height="57"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com isso ele já irá configurar automaticamente suas variáveis de ambiente.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4cHZQWna--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ASfOF691BwUcF_LA1fImbtw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4cHZQWna--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ASfOF691BwUcF_LA1fImbtw.png" alt="" width="800" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pronto agora já podemos utilizar o Puro!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v9iS7Hh9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AaamW9EuuxWDs85aT_WuVWQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v9iS7Hh9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AaamW9EuuxWDs85aT_WuVWQ.png" alt="" width="800" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora podemos criar um novo ambiente utilizando o comando &lt;strong&gt;create&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8kzByXKh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A2wBo5jAiiU4ebKsA_C4sbw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8kzByXKh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A2wBo5jAiiU4ebKsA_C4sbw.png" alt="" width="409" height="50"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O comando é composto por:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;puro create nome_da_versao versao_do_flutter&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Lembrando que o &lt;strong&gt;nome_da_versao&lt;/strong&gt; deve começar com uma letra.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--__T3IVcZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AImB4sU4kuahOhFHl6df7BA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--__T3IVcZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AImB4sU4kuahOhFHl6df7BA.png" alt="" width="425" height="48"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para listar as versões instaladas, basta executar: &lt;strong&gt;puro ls&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HR7nFpVv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AKUnxPpqJC-YHHmfWK5Q_eQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HR7nFpVv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AKUnxPpqJC-YHHmfWK5Q_eQ.png" alt="" width="691" height="209"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para setarmos a versão globalmente no sistema operacional iremos utilizar&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;puro use -g nome_da_versao&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HbMNdy1j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AFjr4CJYy2v3iOLP78kjWEQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HbMNdy1j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AFjr4CJYy2v3iOLP78kjWEQ.png" alt="" width="673" height="83"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Você também pode setar uma versão diferente dentro de um projeto, sendo diferente da versão global, para isso execute: &lt;strong&gt;puro use nome_da_versao&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CCPMz7ot--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AbYfl2LkiKbFq9-b2iIhuIg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CCPMz7ot--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AbYfl2LkiKbFq9-b2iIhuIg.png" alt="" width="781" height="111"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Isso permitirá que utilize versões diferentes em projetos diferentes, sem ter que ficar executando &lt;strong&gt;downgrade&lt;/strong&gt; e &lt;strong&gt;upgrade&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YfYUQm27--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ArRgMa3Q_Yt68Hh6afGfHQw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YfYUQm27--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ArRgMa3Q_Yt68Hh6afGfHQw.png" alt="" width="800" height="179"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Eu particularmente achei muito simples e útil o Puro, mas claro que isso só trará ganhos se você trabalha em mais de um projeto com versões diferentes, que é o caso de vários desenvolvedores.&lt;/p&gt;

&lt;p&gt;Vale lembrar que o Puro é um projeto recente, então usem com cautela!&lt;/p&gt;

&lt;p&gt;Vlw&lt;/p&gt;

&lt;p&gt;😊&lt;/p&gt;

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

&lt;p&gt;Entre em nosso discord para interagir com a comunidade: flutterbrasil.com.br&lt;/p&gt;

</description>
      <category>puro</category>
      <category>version</category>
      <category>management</category>
      <category>flutter</category>
    </item>
    <item>
      <title>Uma nova forma de utilizar os Switch Case no Dart 3</title>
      <dc:creator>Toshi Ossada</dc:creator>
      <pubDate>Sat, 18 May 2024 13:44:07 +0000</pubDate>
      <link>https://dev.to/flutterbrasil/uma-nova-forma-de-utilizar-os-switch-case-no-dart-3-7pm</link>
      <guid>https://dev.to/flutterbrasil/uma-nova-forma-de-utilizar-os-switch-case-no-dart-3-7pm</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ITPSXJwK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ASgpqav1hRit5YgeH0jEcJw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ITPSXJwK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ASgpqav1hRit5YgeH0jEcJw.png" alt="" width="800" height="689"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O Dart 3 nos trouxe muitas novidades incríveis, e já abordei de algumas por aqui, um recurso muito legal foi o que denominamos de &lt;strong&gt;Switch Expressions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A forma tradicional do &lt;strong&gt;Dart&lt;/strong&gt; é utilizarmos o &lt;strong&gt;switch statement&lt;/strong&gt; que é uma forma imperativa e procedural que estamFos acostumados.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Note que, da forma antiga, com a Switch Statement não temos a capacidade de retornar diretamente o valor à variável, com a nova maneira utilizando Switch Expression traz uma importante mudança de introduzir aspectos da programação funcional para o Dart trazendo a linguagem mais flexibilidade e poder.&lt;/p&gt;

&lt;p&gt;Um dos principais avanços das Switch Expressions no Dart 3 é a adoção de uma sintaxe similar às arrow arrow functions para mapear os cases diretamente ao valor de saída. Isso melhora a legibilidade do código e o torna menos propenso a erros.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Note que o default foi &lt;strong&gt;substituído&lt;/strong&gt; apenas pelo &lt;strong&gt;_&lt;/strong&gt; (&lt;strong&gt;underline&lt;/strong&gt;). Podemos melhorar ainda mais nosso código da seguinte forma:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Pattern Matching
&lt;/h3&gt;

&lt;p&gt;Outro recurso bastante interessante é o &lt;strong&gt;Pattern Matching&lt;/strong&gt;, com ele você pode desestruturar um objeto complexo ao mesmo tempo em que está validando uma condição e utilizar esses valores dentro da condição, no Dart 3 você pode utilizar o &lt;strong&gt;Pattern Matching&lt;/strong&gt; dentro de suas condições switchs.&lt;/p&gt;

&lt;p&gt;Veja no exemplo a seguir:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Guard Clauses
&lt;/h3&gt;

&lt;p&gt;Como mostrei em artigos no Dart 3 temos os &lt;strong&gt;records, a&lt;/strong&gt;gora conseguimos usar os &lt;strong&gt;pattern matching&lt;/strong&gt; em conjunto com os &lt;strong&gt;records&lt;/strong&gt;, essa poderosa junção permite com que possamos desestruturar dados e executar uma condição nos dados desestruturados, utilizando a palavra reservada &lt;strong&gt;&lt;em&gt;when&lt;/em&gt;&lt;/strong&gt; para especificar a condição.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Sendo que os valores também podem ser providos de uma função.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Com toda certeza essas novas features deixam o Dart cada vez mais com uma cara de programação funcional, o Dart vem trazendo o que há de melhor da programação funcional e imperativa deixando o código mais legível, eficiente e testável&lt;/p&gt;

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

&lt;p&gt;Entre em nosso discord para interagir com a comunidade: flutterbrasil.com.br&lt;/p&gt;

</description>
      <category>dart3</category>
      <category>dart</category>
      <category>flutter</category>
      <category>switch</category>
    </item>
    <item>
      <title>Novos Modificadores de Classe no Dart 3</title>
      <dc:creator>Toshi Ossada</dc:creator>
      <pubDate>Sat, 18 May 2024 13:38:52 +0000</pubDate>
      <link>https://dev.to/flutterbrasil/novos-modificadores-de-classe-no-dart-3-20bl</link>
      <guid>https://dev.to/flutterbrasil/novos-modificadores-de-classe-no-dart-3-20bl</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i_RKvlLI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ApF-kGlWaQSl0zXoChkAtXg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i_RKvlLI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ApF-kGlWaQSl0zXoChkAtXg.png" alt="dart 3" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No novo Dart 3 tivemos uma mudança bastante interessante que são os novos modificadores de classe, confesso que quando migrei para o Dart achei estranho não termos alguns modificadores de classe, como o &lt;strong&gt;interface&lt;/strong&gt;, e usávamos o &lt;strong&gt;abstract&lt;/strong&gt; para suprir esse déficit.&lt;/p&gt;

&lt;p&gt;Os modificadores de classe podem ser utilizados em uma classe e antes da palavra reservada &lt;strong&gt;class&lt;/strong&gt;, como já estamos acostumados.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--19RUiivg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Ak4w1ng1YNZ6gUr4qNbllow.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--19RUiivg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Ak4w1ng1YNZ6gUr4qNbllow.png" alt="" width="464" height="223"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com o Dart 3 além dos modificadores que já estamos acostumados como &lt;strong&gt;abstract&lt;/strong&gt; e &lt;strong&gt;mixin&lt;/strong&gt; que era possível você &lt;strong&gt;construir, entender ou implementar&lt;/strong&gt; uma classe, agora também temos a &lt;strong&gt;interface&lt;/strong&gt;, &lt;strong&gt;final&lt;/strong&gt;, &lt;strong&gt;sealed&lt;/strong&gt; e &lt;strong&gt;base&lt;/strong&gt; que trazem limitadores na c*&lt;em&gt;onstrução, extensão e implementação&lt;/em&gt;* das classes que possuem esses modificadores, vamos entender o que cada uma traz de novo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interface
&lt;/h3&gt;

&lt;p&gt;Se você chegou a trabalhar com outra linguagem que tem interfaces como &lt;strong&gt;C#&lt;/strong&gt; ou &lt;strong&gt;JAVA&lt;/strong&gt; vai perceber uma diferença com a &lt;strong&gt;interfaces&lt;/strong&gt; do &lt;strong&gt;Dart&lt;/strong&gt;, pois ao contrario das outras linguagens que a interface serve apenas para definir o contrato de métodos, no Dart a &lt;strong&gt;inteface&lt;/strong&gt; define uma classe que pode ser &lt;strong&gt;implementada e construíd&lt;/strong&gt;a, mas não &lt;strong&gt;estendida&lt;/strong&gt; (fora da biblioteca).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Cv6WZti7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A0tD7yQ2KmU7Ka4Vf6iJauA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Cv6WZti7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A0tD7yQ2KmU7Ka4Vf6iJauA.png" alt="" width="469" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oeODXhbl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Aaji02l_3MFBnIvxcyKAsMw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oeODXhbl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Aaji02l_3MFBnIvxcyKAsMw.png" alt="" width="578" height="650"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mas calma, nem tudo está perdido, se você quiser criar uma classe que defina apenas o contrato do que deve ser implementado(com o no &lt;strong&gt;C# ou JAVA&lt;/strong&gt;) adicione o modificador &lt;strong&gt;abstract&lt;/strong&gt; junto a &lt;strong&gt;interface&lt;/strong&gt; , ficando &lt;strong&gt;abtract interface class.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Px_rnnmK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AaHoQNJzU5Vr4CpwXzI7Zxw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Px_rnnmK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AaHoQNJzU5Vr4CpwXzI7Zxw.png" alt="" width="514" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note que a regra de não poder &lt;strong&gt;estender&lt;/strong&gt; uma interface só vale quando é uma classe externa ao arquivo, se estiver dentro do mesmo arquivo ainda assim conseguirei estender a interface (isso vale para a limitação de todos os outros modificadores que iremos falar).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xrZ3Tv75--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A_pTRstZqiKMhH_27G1WhKA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xrZ3Tv75--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A_pTRstZqiKMhH_27G1WhKA.png" alt="" width="684" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se estiver em arquivos separados a regra se mantém e não é possível estender.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8yWg7HLw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Ay-YSy6DinHPu6RQzDSVEfA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8yWg7HLw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Ay-YSy6DinHPu6RQzDSVEfA.png" alt="" width="800" height="91"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Final
&lt;/h3&gt;

&lt;p&gt;Uma classe que contém o modificador &lt;strong&gt;final&lt;/strong&gt; limita que a classe não pode ser &lt;strong&gt;implementada ou estendida&lt;/strong&gt; externamente, mas pode ser &lt;strong&gt;construída.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vamos criar uma classe &lt;strong&gt;final Cachorro.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--n7xDU1Mt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ALR-OP5-PftQLw6EoxzjkdQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--n7xDU1Mt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ALR-OP5-PftQLw6EoxzjkdQ.png" alt="" width="425" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se criarmos outra classe e &lt;strong&gt;estender&lt;/strong&gt; de &lt;strong&gt;Cachorro&lt;/strong&gt; não será possível e irá apresentar um erro.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--f8sQRf1X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Amk2tC05uwb1u_U9QW84f9g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f8sQRf1X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Amk2tC05uwb1u_U9QW84f9g.png" alt="" width="800" height="96"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Base
&lt;/h3&gt;

&lt;p&gt;Já o modificador &lt;strong&gt;Base&lt;/strong&gt; diferente da &lt;strong&gt;interface&lt;/strong&gt; não permite que a classe seja implementada em uma outra classe que esteja externo ao biblioteca, mas permite que ela seja &lt;strong&gt;construída ou estendida.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Além do mais, as subclasses que irão estender a classe base deverão ser uma classe com os modificadores &lt;strong&gt;final&lt;/strong&gt; ou &lt;strong&gt;sealed&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8cnB5XAX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Agbrzq1op3C40-FnXt4_3ew.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8cnB5XAX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Agbrzq1op3C40-FnXt4_3ew.png" alt="" width="356" height="233"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se tentarmos estender da classe &lt;strong&gt;Animal&lt;/strong&gt; irá ocorrer um erro:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7kWWbJoj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AUmf9uDH8z1EbjVBjE9fjQg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7kWWbJoj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AUmf9uDH8z1EbjVBjE9fjQg.png" alt="" width="800" height="98"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para resolver o problema a classe &lt;strong&gt;Cachorro&lt;/strong&gt; deverá ser &lt;strong&gt;final&lt;/strong&gt; ou &lt;strong&gt;sealed&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nKgbEJUw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Aj1JoKnz9oYH_quVUEn0dGg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nKgbEJUw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Aj1JoKnz9oYH_quVUEn0dGg.png" alt="" width="573" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se tentar &lt;strong&gt;implementar&lt;/strong&gt; a classe &lt;strong&gt;Animal&lt;/strong&gt; também não será possível.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GrHZn2GK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AZs5RbSYpoeawCHrqnCyumw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GrHZn2GK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AZs5RbSYpoeawCHrqnCyumw.png" alt="" width="800" height="97"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vale lembrar que assim como nas &lt;strong&gt;interfaces&lt;/strong&gt; é possível adicionar o modificador &lt;strong&gt;abstract base&lt;/strong&gt; para que não precise implementar os métodos na classe &lt;strong&gt;base&lt;/strong&gt; deixando apenas os contratos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uJ4Hlrdx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AuVtmXnyjk4C4OoqjF_UYng.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uJ4Hlrdx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AuVtmXnyjk4C4OoqjF_UYng.png" alt="" width="463" height="236"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Sealed
&lt;/h3&gt;

&lt;p&gt;O modificador sealed é um dos mais restritivos dentro do Dart, com ela a classe não poderá ser &lt;strong&gt;implementada&lt;/strong&gt;, &lt;strong&gt;estendida&lt;/strong&gt; e nem &lt;strong&gt;construída&lt;/strong&gt; externamente, o uso dela será restrito para uso &lt;strong&gt;interno da biblioteca&lt;/strong&gt; e possibilitara a checagem exaustiva de suas subclasses no switch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9S83L2tt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AftczZrCQg-s2PjsJg959EA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9S83L2tt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AftczZrCQg-s2PjsJg959EA.png" alt="" width="700" height="786"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora se fizermos um switch verificando os tipos do &lt;strong&gt;Failure&lt;/strong&gt; o &lt;strong&gt;linter&lt;/strong&gt; já irá retornar um erro dizendo para verificar todas as subclasses de &lt;strong&gt;Failure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AcyIt_qn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AB_hgOZx4LT7fE_WiD8NJcQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AcyIt_qn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AB_hgOZx4LT7fE_WiD8NJcQ.png" alt="" width="800" height="104"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SCRHo_3n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Afic99By-uyXDJnaXraPSeQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SCRHo_3n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Afic99By-uyXDJnaXraPSeQ.png" alt="" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Muito bacana esses novos modificadores né? Para mais informações procure na documentação oficial do dart &lt;a href="https://dart.dev/language/class-modifiers"&gt;https://dart.dev/language/class-modifiers&lt;/a&gt; ou em &lt;a href="https://dart.dev/language/modifier-reference#valid-combinations"&gt;https://dart.dev/language/modifier-reference#valid-combinations&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Nosso querido Professor Diego também tem um vídeo bem bacana sobre esse assunto, confira abaixo:&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=E6jfQwaLtik"&gt;&lt;br&gt;
 &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JblzriwQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.youtube.com/vi/E6jfQwaLtik/0.jpg" alt="Monorepo (Por Que Essa Estratégia Funciona em Grandes Empresas?) " width="480" height="360"&gt;&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vlw! 😉&lt;/p&gt;

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

&lt;p&gt;Entre em nosso discord para interagir com a comunidade: flutterbrasil.com.br&lt;/p&gt;

</description>
      <category>modificadores</category>
      <category>acesso</category>
      <category>dart3</category>
      <category>dart</category>
    </item>
    <item>
      <title>Multiplos retornos no Flutter/DART com os Records</title>
      <dc:creator>Toshi Ossada</dc:creator>
      <pubDate>Sat, 18 May 2024 13:35:50 +0000</pubDate>
      <link>https://dev.to/flutterbrasil/multiplos-retornos-no-flutterdart-com-os-records-3e45</link>
      <guid>https://dev.to/flutterbrasil/multiplos-retornos-no-flutterdart-com-os-records-3e45</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--s9EJPhSC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/0%2AR97t9T6hDW7XmFCB.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--s9EJPhSC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/0%2AR97t9T6hDW7XmFCB.png" alt="" width="700" height="222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No último dia 10 de maio, ocorreu o Google IO, obviamente não foi um evento voltado para (somente) programação e sim um evento que anuncia todos os seus próximos lançamentos como o Bard, Pixel Tablet, Pixel Fold, Pixel Watch. etc.&lt;/p&gt;

&lt;p&gt;Claro todos estávamos ansiosos com o lançamento do Dart 3 que foi anunciado em janeiro no Flutter Forward, e foi exatamente isso que aconteceu, Dart 3 na Stable junto com a vinda do Flutter 3.10, muitos acabaram se decepcionando pois estavam com expectativas muito elevadas achando que viria novidade, mas as novidades eram as que foram anunciadas no Flutter Forward.&lt;/p&gt;

&lt;p&gt;Uma das features que eu particularmente estava aguardando é a possibilidade de sua função conseguir retornar mais de um valor, e isso hoje é possível aos records.&lt;/p&gt;

&lt;p&gt;Basicamente é só colocar os tipos dos retornos entre parênteses e receber nas variáveis, também em parênteses, descontruindo os retornos&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;No retorno ao invés de receber em várias variáveis posso também receber em apenas uma e acessar de forma posicional.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Também conseguimos passar o retorno de forma nomeada, basta colocar o nome do retorno na frente do tipo do dado&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Caso queiramos ignorar alguns dos retornos basta usar o underline como nome da variável de retorno&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Com isso podemos fazer tratamento de erros que nem é de costume fazer em algumas linguagens como o Go Lang de retornar um Erro ou o valor da função e depois de retornarmos validamos se o erro foi retornado&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;A dúvida de muitos será, isso substitui o DartZ? E a resposta é depende, se utiliza o DartZ apenas para retornar dois valores sim, entretanto o DartZ tem muitas outras features que nos auxiliam no desenvolvimento.&lt;/p&gt;

&lt;p&gt;Muito bacana essa nova funcionalidade no Dart 3 né? Pode não parecer grande coisa, mas eu, que trabalhei com linguagens que tinham essa possibilidade, posso te garantir que ajuda bastante. Além do mais os records possibilitaram outras features mais interessantes como os Destructuring e os records patterns que iremos ver nos proximos artigos :)&lt;/p&gt;

&lt;p&gt;Tem vários exemplos em meu github &lt;a href="https://github.com/toshiossada"&gt;https://github.com/toshiossada&lt;/a&gt; Dê uma olhada e deixe suas estrelinhas! :)&lt;/p&gt;

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

&lt;p&gt;Entre em nosso discord para interagir com a comunidade: flutterbrasil.com.br&lt;/p&gt;

</description>
      <category>records</category>
      <category>dart</category>
      <category>flutter</category>
    </item>
    <item>
      <title>Offline First no Flutter utilizando o DIO e Hive</title>
      <dc:creator>Toshi Ossada</dc:creator>
      <pubDate>Wed, 01 May 2024 01:40:19 +0000</pubDate>
      <link>https://dev.to/flutterbrasil/offline-first-no-flutter-utilizando-o-dio-e-hive-29pb</link>
      <guid>https://dev.to/flutterbrasil/offline-first-no-flutter-utilizando-o-dio-e-hive-29pb</guid>
      <description>&lt;p&gt;Quando desenvolvemos um aplicativo é muito comum termos dependência de dados que vem da internet, entretanto garantir que o usuário esteja 100% do tempo conectado á rede mundial de computadoress é uma tarefa impossível.&lt;/p&gt;

&lt;p&gt;Com este problema em vista várias empresas adotam o conceito do Offline First, para garantir que algumas funcionalidades permaneçam funcionando mesmo que o usuário esteja desconectado a uma rede de internet.&lt;/p&gt;

&lt;p&gt;O offline first trabalha com o conceito de local storage, que basicamente iremos armazenar informações que virão da internet (uma requisição da api) para quando o dispositivo do usuário estiver desconectado (ou até mesmo para não precisar fazer várias requisições desnecessárias) ele consiga utilizar algumas funções.&lt;/p&gt;

&lt;p&gt;Para este artigo utilizaremos o Dio como cliente HTTP e o hive como banco de dados local, também precisaremos do build_runner e do hive_generator&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Primeiramente vamos construir o modelo que iremos salvar nossos dados offline (cache) , nele iremos precisar de um campo identificador, um para a data de atualização e um campo que irá conter o Map do resultado da API.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1mqw-zyv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ATvkn6GImmdF2l1LQe0J19w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1mqw-zyv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ATvkn6GImmdF2l1LQe0J19w.png" alt="" width="281" height="144"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Será necessário executar o build_runner&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;flutter pub run build_runner build&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nesse momento podemos criar a classe que ficará responsável por gerenciar este banco de dados local, chamaremos de cache_adapter. Nele teremos um método para recuperar o dado salvo em um determinado id, e outro para inserir/atualizar o valor armazenado&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Podemos melhorar este código e fazer a segregação por interface&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--m9FsqxWU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AnvBD3Cm6iCHerC5SovxIUw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--m9FsqxWU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AnvBD3Cm6iCHerC5SovxIUw.png" alt="" width="272" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora vamos fazer um simples caso de uso que irá verificar se o dispositivo está conectado a internet.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Agora no Dio precisamos criar um Interceptador pois iremos interceptar o métodos onRequest e onResponse. Neles vamos receber via injeção de dependências pelo construtor tanto a classe que irá gerenciar o cache, quanto o caso de uso que irá verificar a conectividade&lt;/p&gt;

&lt;p&gt;Se não faz ideia do que são interceptadores do DIO tem um artigo bem legal que escrevi a um tempo explicando-os &lt;a href="https://toshiossada.medium.com/consumindo-api-utilizando-o-dio-9ec72aeceeaa"&gt;https://toshiossada.medium.com/consumindo-api-utilizando-o-dio-9ec72aeceeaa&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Agora no método onResponse vamos armazenar o resultado da consulta quando fizermos uma requisição GET e colocaremos um tempo de validade de cinco minutos no cache armazenado. Note que como id usaremos o path da requisição GET, pois desta maneira toda vez que ele fizer requisição para o mesmo endpoint iremos atualizar o valor para o mais atual.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;No Método onRequest chamamos o caso de uso para verificar a conectividade do dispositivo e caso não esteja conectado iremos recuperar o valor armazenado para aquela URL.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Desta forma mesmo com o dispositivo offline conseguiremos continuar fazendo a busca&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J93UZ4VN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AMthm8FaJ9uYq1wZa9kfefw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J93UZ4VN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AMthm8FaJ9uYq1wZa9kfefw.gif" alt="" width="369" height="749"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Legal né? Agora você pode utilizar esta ideia e evoluir seus aplicativo para funcionar de forma offline&lt;/p&gt;

&lt;p&gt;Acesse o projeto de exemplo&lt;br&gt;
&lt;a href="https://github.com/toshiossada/termo_hack"&gt;https://github.com/toshiossada/termo_hack&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Entre em nosso discord para interagir com a comunidade: &lt;a href="https://discord.com/invite/flutterbrasil"&gt;https://discord.com/invite/flutterbrasil&lt;/a&gt;&lt;br&gt;
&lt;a href="https://linktr.ee/flutterbrasil"&gt;https://linktr.ee/flutterbrasil&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Publicando seus packages no pub.dev</title>
      <dc:creator>Toshi Ossada</dc:creator>
      <pubDate>Wed, 01 May 2024 01:32:31 +0000</pubDate>
      <link>https://dev.to/flutterbrasil/publicando-seus-packages-no-pubdev-2gjd</link>
      <guid>https://dev.to/flutterbrasil/publicando-seus-packages-no-pubdev-2gjd</guid>
      <description>&lt;p&gt;Fala Devs, é muito comum quando vamos desenvolver um app a recorrermos a utilização de packages lá no pub.dev, lá tem packages realmente uteis e aposto que você já teve uma ideia que também iria ajudar alguém, o que alguns talvez não saibam é que todos nós podemos submeter nossos packages para serem utilizados lá, além disso podemos criar nosso projeto orientados a packages onde criamos cada feature de nosso projeto e disponibilizamos por meio de packages para o restante do nosso time. Neste artigo iremos criar um package para ser publicado no pub.dev.&lt;/p&gt;

&lt;p&gt;Primeiramente precisamos criar nosso projeto com o flutter create, mas antes de realizarmos o create vamos adicionar o argumento -h para saber o que podemos fazer no flutter create.&lt;/p&gt;

&lt;p&gt;Observe que temos o argumento — template= é exatamente este argumento que utilizaremos para gerar o package, em especial temos o tipo package e plugins, basicamente packages são pacotes em código puro em dart e plugins são pacotes que usarão código nativo (kotlin ou swift), no artigo de hoje iremos utilizar o package.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TAR-wPbt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AzcVwPLKlkrijXnLPPw9FYw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TAR-wPbt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AzcVwPLKlkrijXnLPPw9FYw.png" alt="" width="567" height="156"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8qdVWgFQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ACPTgHPswMBH5akwsTnYzpQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8qdVWgFQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ACPTgHPswMBH5akwsTnYzpQ.png" alt="" width="446" height="41"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com isso teremos uma estrutura bem semelhante ao do app em flutter&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ddVDaNDL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AgZBDtQ1Wdzxa7TqxXs_V7A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ddVDaNDL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AgZBDtQ1Wdzxa7TqxXs_V7A.png" alt="" width="412" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E se observarmos o pubspec ele também é bem parecido, ele possui algumas informações a mais como nome do package, descrição, versão etc. também podemos adicionar dependências, vamos adicionar o Dio.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--G39bLuqE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AtS3NScteIuaabgFfHvqzrw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--G39bLuqE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AtS3NScteIuaabgFfHvqzrw.png" alt="" width="512" height="294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IxpUPIio--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AMVfeD30siyusfx1eVj0KRA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IxpUPIio--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AMVfeD30siyusfx1eVj0KRA.png" alt="" width="482" height="192"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como se trata de um package é muito importante em tomar cuidado de que as dependências que utilizamos não quebre com a versão conforme a versão (e ao mesmo tempo não deixarmos obsoletas) então na versão vamos utilizar a notação &amp;gt;= 3.0.9 &amp;lt; 4.0.0, isso significa que ele ira utilizar o DIO na versão mais recente a partir da 3.0.9 e até a versão 4.0.0, isso porque quando mudar a major version significa que o package teve uma grande break change e provavelmente irá fazer com que meu código quebre.&lt;/p&gt;

&lt;p&gt;Vamos também alterar a description, esta informação é a que aparecerá no about do seu package no pub.dev.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---tb8FbHN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Aqmwv6nMvF4_Ug8EnyCQp8w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---tb8FbHN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Aqmwv6nMvF4_Ug8EnyCQp8w.png" alt="" width="567" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zH7Pt5A2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AGj22gRTAaXySiCwu4HF2tQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zH7Pt5A2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AGj22gRTAaXySiCwu4HF2tQ.png" alt="" width="311" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qWvgcYmG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AVY7YDVlw5tDF8sI0V0BLMg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qWvgcYmG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AVY7YDVlw5tDF8sI0V0BLMg.png" alt="" width="312" height="56"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Algo bastante importante a se fazer (caso deseje publicar seu package no pub.dev) é criar um projeto de exemplo chamado exemplo dentro do projeto do seu package, mostrando em como você deve utilizar seu package.&lt;/p&gt;

&lt;p&gt;Com isso você já pode ir ao pubspec do seu projeto ‘example’ e adicionar referência para seu package&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dn-FBUiC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AURKFd4Thlvcvm7NpiFGUZg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dn-FBUiC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AURKFd4Thlvcvm7NpiFGUZg.png" alt="" width="420" height="632"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xX0gScoD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ATNGghhGNqyW5KzDB30oriw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xX0gScoD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ATNGghhGNqyW5KzDB30oriw.png" alt="" width="415" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Utilizaremos o nome que está no arquivo principal do seu package&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vP_bsLpa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AquWcMYx1h5CEFyBYzglOOw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vP_bsLpa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AquWcMYx1h5CEFyBYzglOOw.png" alt="" width="303" height="236"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feito isso vamos voltar ao projeto do nosso package e estruturá-lo da seguinte maneira.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NYSLhx3z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AYRItqH2tpKM5E9TYMU38Mw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NYSLhx3z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AYRItqH2tpKM5E9TYMU38Mw.png" alt="" width="290" height="222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em nossa model vamos prepará-la para receber o JSON e armazenar o id, o nome do Pokémon e a url da imagem.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XMV_174d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AQ1rME3zlD6_3L3stalAw1Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XMV_174d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AQ1rME3zlD6_3L3stalAw1Q.png" alt="" width="567" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em nosso repository apenas iremos fazer uma requisição ao &lt;a href="https://pokeapi.co/api/v2/pokemon/num"&gt;https://pokeapi.co/api/v2/pokemon/num&lt;/a&gt; utilizando o Dio, passando o número como parâmetro, isso me retornara informações do Pokémon&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Skx_nYWs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AlQb0KIh7HhpZFVgNM1EckA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Skx_nYWs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AlQb0KIh7HhpZFVgNM1EckA.png" alt="" width="566" height="236"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Já no meu controller apenas terei o método que recebera um número e irá chamar meu get() do repository&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--58NQ6I5m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AEMojHffTu_6Rb_cJtrN1MA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--58NQ6I5m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AEMojHffTu_6Rb_cJtrN1MA.png" alt="" width="397" height="103"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enfim, tenho um widget que tem um FutureBuilder que receberá o retorno da função get do controller e irá tratar o retorno para montar uma coluna com a imagem do Pokémon e o nome e o número em cima.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8Okqsj5e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AobUrKeB6JCFNziQtJidfEA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8Okqsj5e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AobUrKeB6JCFNziQtJidfEA.png" alt="" width="567" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora no meu arquivo principal eu preciso exportar meu widget para que meu aplicativo consiga enxergar meu widget (poderia exportar aquilo que eu quiser como os modelos e até mesmo os repositories)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NSQDbNrT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ACYi2vjKgS4_I9YUn20HoOg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NSQDbNrT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ACYi2vjKgS4_I9YUn20HoOg.png" alt="" width="410" height="177"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora voltamos ao meu app de exemplo para testarmos a implementação do meu package.&lt;/p&gt;

&lt;p&gt;No arquivo main.dart vamos importar o widget do meu package&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4h9ygupz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ApbtszRXh3u7QMYxek8IG7g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4h9ygupz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ApbtszRXh3u7QMYxek8IG7g.png" alt="" width="542" height="138"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E já na minha HomePage posso chamar meu widget Pokemon() passando o parâmetro num.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QCiG-pHB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AOm4BaeF-7mt1puiQhongNA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QCiG-pHB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AOm4BaeF-7mt1puiQhongNA.png" alt="" width="566" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Desta forma ao rodarmos o App teremos o seguinte resultado&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tbO5bttj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AnyAtFPig7Qh06fRYaZJQjQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tbO5bttj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AnyAtFPig7Qh06fRYaZJQjQ.png" alt="" width="385" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pronto! meu package está pronto para uso, caso eu queira deixar meus packages privados para utilização de um projeto interno utilizando a orientação a packages, eu paro por aqui, coloco em um repositório privado da minha empresa e utilizo ele em meu projeto. Mas a intenção do artigo é também mostrar como podemos publicá-los em modo público lá no pub.dev.&lt;/p&gt;

&lt;p&gt;Então vamos seguir em frente, é uma boa publicarmos nosso package lá no github em um repositório público. Para isso vamos lá no github, clicamos em New&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nFapb-WW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A3_TTGaUy4gMAStdalOttgA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nFapb-WW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A3_TTGaUy4gMAStdalOttgA.png" alt="" width="566" height="232"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Depois damos um nome para o repositório e uma descrição&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tTjxa3mj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AMcP3cOly_S3AvpTYAQOUBQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tTjxa3mj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AMcP3cOly_S3AvpTYAQOUBQ.png" alt="" width="566" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Depois voltamos no terminal aberto la no nosso projeto e primeiramente iniciaremos o git na nossa pasta com git init&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SwvLBzH5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AqGCS6JK5qQnAQRv_CvvI0g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SwvLBzH5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AqGCS6JK5qQnAQRv_CvvI0g.png" alt="" width="566" height="36"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Temos que adicionar as alterações no nosso repositório local com git add .&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IXjY-c-3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A58mICufNlX4Ow1Zej_okpw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IXjY-c-3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A58mICufNlX4Ow1Zej_okpw.png" alt="" width="567" height="91"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E agora commitar nossas alterações&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PbhCPsrO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AnUzrlLgY-lNW_APQQGYy4Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PbhCPsrO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AnUzrlLgY-lNW_APQQGYy4Q.png" alt="" width="436" height="56"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em seguida vamos apontar o git para o endereço do nosso github&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I8iePrf3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A92anWo1HS0S4hoBbzY2Q0A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I8iePrf3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A92anWo1HS0S4hoBbzY2Q0A.png" alt="" width="567" height="23"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E finalmente dar um git push para empurrar nossas alterações para o repositório (no caso o github)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--56BAsf8v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AUVkcuSxo_0g4pwTDICmtcQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--56BAsf8v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AUVkcuSxo_0g4pwTDICmtcQ.png" alt="" width="325" height="57"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feito isso nosso código estará lá no github&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BeT1chbO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AhIaEYghSbrH--SrvSoQKXg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BeT1chbO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AhIaEYghSbrH--SrvSoQKXg.png" alt="" width="567" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora podemos alterar a homepage no pubspec do nosso package para o endereço do github.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--76Vhlgbz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A71glgA8PxSKd5Lx5MIyvhQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--76Vhlgbz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A71glgA8PxSKd5Lx5MIyvhQ.png" alt="" width="567" height="106"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Temos também um arquivo de Changelog, lá é onde colocaremos as modificações do package conforme a versão&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ySoDKGzO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A6wB07qAvMiuyu9pcOeF4KA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ySoDKGzO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A6wB07qAvMiuyu9pcOeF4KA.png" alt="" width="567" height="562"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ele vai aparecer lá no site do pub.dev na aba changelog&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WHbiyWfo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A60Rc3AtqDnM9f09fSdmATg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WHbiyWfo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A60Rc3AtqDnM9f09fSdmATg.png" alt="" width="567" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feito isso é só publicar o package flutter pub publish, mas antes disso vamos ver o -h&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4Wqs-lIf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AyJa_YM23CZnX_5WP8QOlgQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4Wqs-lIf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AyJa_YM23CZnX_5WP8QOlgQ.png" alt="" width="567" height="151"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lá temos o argumento –dry-run, este argumento serve para verificar se está tudo certo no seu package e se está sem nenhuma pendência para ser publicado.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I7fYloWN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A6bAdA3BKjYWuABfz10RiCA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I7fYloWN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A6bAdA3BKjYWuABfz10RiCA.png" alt="" width="566" height="597"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--stn6_KxL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ALDCkaf8_D9S3sg7R9gi1Ng.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--stn6_KxL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ALDCkaf8_D9S3sg7R9gi1Ng.png" alt="" width="379" height="105"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se estiver tudo certo aparecera esta mensagem. Agora sim podemos publicar&lt;/p&gt;

&lt;p&gt;Vai pedir para você confirmar&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Jsu_L8yw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AfF46CdLZdDHqSCZvW7B4DQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Jsu_L8yw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AfF46CdLZdDHqSCZvW7B4DQ.png" alt="" width="198" height="24"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yonsa9Vc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ApVRJcrLYblqmO4G3KS6hyw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yonsa9Vc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ApVRJcrLYblqmO4G3KS6hyw.png" alt="" width="467" height="74"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Logo em seguida ele irá pedir para realizar login na sua google account, basta entrar no link e fazer o login&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--igF2VXWz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AwHeD7ALRQuCxtEQcps9ZVA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--igF2VXWz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AwHeD7ALRQuCxtEQcps9ZVA.png" alt="" width="565" height="47"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DLLWflDd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ANowjXBTQRjFg0zOC5HuLfQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DLLWflDd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ANowjXBTQRjFg0zOC5HuLfQ.png" alt="" width="567" height="143"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yOQvCyow--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AG17infi6xCXLtl7mcYDuOg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yOQvCyow--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AG17infi6xCXLtl7mcYDuOg.png" alt="" width="566" height="161"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Depois de fazer o login aparecera a mensagem de sucesso&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vnw7Yy-f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ArzrHFBPljXE9O9cXI4rtfw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vnw7Yy-f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ArzrHFBPljXE9O9cXI4rtfw.png" alt="" width="388" height="111"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A aparição do seu package no pub.dev não é imediata, leva um tempo ate replicar em todos os servidores, mas se voltar em alguns minutos já irá ver seu package publicado&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tI2aSD0B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A69ybq_jXs7ZpdWIA4M2f4g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tI2aSD0B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2A69ybq_jXs7ZpdWIA4M2f4g.png" alt="" width="562" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R8XGFcpx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AHwYYlWxv9U_HaBl1Pwr__Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R8XGFcpx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AHwYYlWxv9U_HaBl1Pwr__Q.png" alt="" width="567" height="323"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Viu só? É muito facil construir um package, agora você já pode fazer o seu.&lt;/p&gt;

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

&lt;p&gt;Entre em nosso discord para interagir com a comunidade: &lt;a href="https://discord.com/invite/flutterbrasil"&gt;https://discord.com/invite/flutterbrasil&lt;/a&gt;&lt;br&gt;
&lt;a href="https://linktr.ee/flutterbrasil"&gt;https://linktr.ee/flutterbrasil&lt;/a&gt;&lt;/p&gt;

</description>
      <category>packages</category>
      <category>pubdev</category>
      <category>publishing</category>
      <category>flutter</category>
    </item>
    <item>
      <title>Executando processos paralelos com Flutter/DART</title>
      <dc:creator>Toshi Ossada</dc:creator>
      <pubDate>Fri, 26 Apr 2024 14:18:42 +0000</pubDate>
      <link>https://dev.to/flutterbrasil/executando-processos-paralelos-com-flutterdart-3fjg</link>
      <guid>https://dev.to/flutterbrasil/executando-processos-paralelos-com-flutterdart-3fjg</guid>
      <description>&lt;h3&gt;
  
  
  Executando processos paralelos com Flutter/DART
&lt;/h3&gt;

&lt;p&gt;O Flutter que conhecemos tem uma execução num único thread e essa thread é executada em único, o que chamamos, de isolate.&lt;/p&gt;

&lt;p&gt;Essa isolate, conhecida como main isolate, e as vezes necessitamos executar processos que podem gerar concorrência então a main isolate faz toda a gerência de seu event loop para que possamos executar códigos de forma assíncrona.&lt;/p&gt;

&lt;p&gt;Então quer dizer que se eu tiver uma tarefa que executa muito tempo basta colocar no event loop que não terei problema? errado! há casos que temos tarefas muito pesados que causara gargalo em meu event loop (que também contém instruções de renderização) e irá causar travamentos (janks) na tela.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hmdulX3G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Ak6NZW_99xedjfLY7RqOHww.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hmdulX3G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Ak6NZW_99xedjfLY7RqOHww.png" alt="" width="800" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KJ2z854o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ArdWmLPYm2mtzjuhyUPlAiw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KJ2z854o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ArdWmLPYm2mtzjuhyUPlAiw.gif" alt="" width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No exemplo acima temos uma animação que roda constantemente, mas perceba-se que quando executamos uma função, no caso o cálculo de Fibonacci, que é um cálculo custoso.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Nesse caso a solução seria fazer um processamento paralelo ao main isolate criando um novo isolate (já que Future, event loops, etc NÃO É processamento paralelo).&lt;/p&gt;

&lt;p&gt;Mas o que são isolates?&lt;/p&gt;

&lt;p&gt;O dart utiliza isolates que executam suas instruções de forma sequencial e em uma região da memória dedicada a ela. Cada isolate tem sua memória dedicada e seu próprio event loop que são isolados para esse propósito. diferente das threads esses isolates não podem acessar os dados um dos outros diretamente. Toda comunicação deve ser feita através de mensagens.&lt;/p&gt;

&lt;p&gt;Afim de prever alguns erros comuns na utilização de threads como: mutabilidade de dados, os clássicos problemas de bloqueios, &lt;em&gt;dead-locks,&lt;/em&gt; etc. que são bastante comuns em programação paralela.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5oYNFP6g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AsQ1ZweJd7jSyM9ySvH-Egw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5oYNFP6g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AsQ1ZweJd7jSyM9ySvH-Egw.gif" alt="" width="611" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para trabalharmos para criar isolates existem basicamente duas formas, a primeira forma mais simples é utilizando o método &lt;strong&gt;compute().&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O método &lt;strong&gt;compute()&lt;/strong&gt; recebe 2 parâmetros, o primeiro é um método(&lt;strong&gt;NOTE QUE ESSE MÉTODO NECESSITA SER STATIC&lt;/strong&gt;) que será executado dentro da isolate que será criado e o outro é o parâmetro que irá passar da main isolate para a nova isolate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XUafV55e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AMelqvpAwqKbC5x4foLrAeA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XUafV55e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AMelqvpAwqKbC5x4foLrAeA.png" alt="" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao final da execução da isolate ela irá retornar um valor para a mais isolate, não há necessidade de preocupar com o fechamento da isolate e não há comunicação por mensagens entre a isolate criada e a main isolate.&lt;/p&gt;

&lt;p&gt;A segunda forma mais completa é utilizando o &lt;strong&gt;Isolate.spawn()&lt;/strong&gt;, este também possui dois parâmetros igualmente o &lt;strong&gt;compute()&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KVySqw1p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ACwtQniM95s_xYw786Lzf6g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KVySqw1p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2ACwtQniM95s_xYw786Lzf6g.png" alt="" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nesse caso criamos um Objeto chamado &lt;strong&gt;Message&lt;/strong&gt; que iremos utilizar como parâmetro do método a ser executado dentro da isolate, criamos o &lt;strong&gt;ReceiverPort&lt;/strong&gt; que é uma abstração que implementa uma stream através dele conseguimos passar o &lt;strong&gt;sendPort&lt;/strong&gt; para a nova &lt;strong&gt;isolate&lt;/strong&gt;. Através deles conseguimos fazer a comunicação entre as duas isolates, onde as mensagens enviadas pelo &lt;strong&gt;sendPort&lt;/strong&gt; são capturadas no &lt;strong&gt;ReceivePort&lt;/strong&gt; e como trata de uma &lt;strong&gt;Stream&lt;/strong&gt;, podemos escutar essas mensagens.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;O método &lt;strong&gt;Isolate.exit()&lt;/strong&gt; faz a transferência de dados para o &lt;strong&gt;Isolate&lt;/strong&gt; receptor, que nesse exemplo seria o main.&lt;/p&gt;

&lt;p&gt;Algumas vantagens na utilização de isolates são:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A possibilidade de execução de operações computacionais custosas de forma performática;&lt;br&gt;
Possibilita a experiencia fluida de animações.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Então agora vou utilizar isolates a rodo em meu projeto? Não, nem tudo são flores, então existem desvantagens de utilizar isolates, como:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Complexidade de código;&lt;br&gt;
É um processo extremamente custoso ao dispositivo, principalmente em questão de memória.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Então nosso exemplo do Fibonacci ficaria da seguinte forma.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Note que não há mais problemas de janks na execução do calculo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4VBomOgE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Ai3EbD2c8V_FE1VnxSE-Stw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4VBomOgE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Ai3EbD2c8V_FE1VnxSE-Stw.gif" alt="" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora imagine o caso em que eu preciso que você tem um aplicativo aplicando todos os bons conceitos do SOLID e utiliza um package de &lt;strong&gt;service locator&lt;/strong&gt; para resolver as dependências de sua classe?&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Você recebe a &lt;strong&gt;usecase&lt;/strong&gt; por construtor da &lt;strong&gt;controller.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1iLrc6En--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AZz21yJ7OFxYiRAGMN3cAyw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1iLrc6En--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AZz21yJ7OFxYiRAGMN3cAyw.png" alt="" width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E tenta executar o caso de uso dentro da isolate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sIogCf-q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Ay-LZd2y_Y5RJbBIC6Z_YsQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sIogCf-q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Ay-LZd2y_Y5RJbBIC6Z_YsQ.png" alt="" width="800" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Isso não será possível simplesmente pelo fato de que a inicialização dos &lt;strong&gt;Binds&lt;/strong&gt; (no caso do Modular) terem sido feito na memória da main isolate e como não há compartilhamento de memoria entre os isolates. Uma solução é fazer a inicialização dos &lt;strong&gt;Binds&lt;/strong&gt; novamente do package que escolheu para &lt;strong&gt;service locator&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;No caso do Flutter Modular podemos criar um modulo isolado contendo todas as instancias de classe que iremos utilizar dentro do isolate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FcEkt-Ok--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AcdGy6hsGEPYBo8-lhlBQ0Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FcEkt-Ok--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AcdGy6hsGEPYBo8-lhlBQ0Q.png" alt="" width="592" height="511"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;e através do &lt;strong&gt;Modular.init()&lt;/strong&gt; podemos inicializar dentro da isolate o modulo novo.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iyJmcnsI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AMKfaTGYJpxA6xzbmV47cJQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iyJmcnsI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AMKfaTGYJpxA6xzbmV47cJQ.png" alt="" width="800" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dessa forma conseguimos recuperar as instancias através do &lt;strong&gt;Modular.get().&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Legal né? Muito simples fazer programaçao paralela no Dart, tem um exemplo muito legal no meu github, entre lá confira e dar estrelinha no repositório.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/toshiossada/hive_example"&gt;https://github.com/toshiossada/hive_example&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Entre em nosso discord para interagir com a comunidade: &lt;a href="https://discord.com/invite/flutterbrasil"&gt;https://discord.com/invite/flutterbrasil&lt;/a&gt;&lt;br&gt;
&lt;a href="https://linktr.ee/flutterbrasil"&gt;https://linktr.ee/flutterbrasil&lt;/a&gt;&lt;/p&gt;

</description>
      <category>isolates</category>
      <category>thread</category>
      <category>dart</category>
      <category>isolate</category>
    </item>
  </channel>
</rss>
