O que há de novo no Flutter 3.7

Tempo de leitura: 12 minutes

Estamos ansiosos para começar 2023 com o lançamento do Flutter 3.7! No Flutter 3.7, nós, como comunidade, continuamos a melhorar a estrutura com a adição de alguns novos recursos excelentes, como: a capacidade de criar barras de menu personalizadas, menus em cascata, ferramentas para oferecer melhor suporte à internacionalização, novas ferramentas de depuração e muito mais.

Também continuamos a refinar recursos como seleção global, renderização mais rápida com Impeller, DevTools e, como sempre, desempenho!

Vamos fazer uma rápida jornada juntos para explorar os novos recursos do Flutter 3.7!

 

Suporte aprimorado para Material 3

O suporte ao Material 3 foi bastante aprimorado na versão 3.7 com a migração dos seguintes widgets:

 

Para usar esses novos recursos, basta ativar o sinalizador useMaterial3 no widget ThemeData do seu aplicativo. Para aproveitar ao máximo o suporte M3, você precisará de um esquema de cores M3 completo. Você pode fornecer o seu próprio, usar a nova ferramenta de criação de temas ou o Flutter pode gerar uma para você a partir de uma única cor de semente usando o parâmetro colorSchemeSeed do construtor ThemeData:

MaterialApp(
  theme: ThemeData(
     useMaterial3: true,
    colorSchemeSeed: Colors.green,
  ),
  // …
);

Para obter os detalhes mais recentes do suporte ao Material 3 do Flutter, consulte o problema geral no GitHub.

Para brincar com esses componentes, confira a demonstração interativa que mostra todos os novos recursos do M3:

Barras de menu e menus em cascata

O Flutter agora pode criar barras de menu e menus de contexto em cascata.

Para macOS, crie uma barra de menu usando o widget PlatformMenuBar, que define as barras de menu nativas da plataforma renderizadas pelo macOS em vez do Flutter.

E, para todas as plataformas, você pode definir um menu Material Design que forneça barras de menu em cascata (MenuBar) ou menus em cascata autônomos acionados por outro elemento da interface do usuário (MenuAnchor). Esses menus são totalmente personalizáveis e os itens de menu podem ser widgets personalizados ou você pode usar os novos widgets de item de menu (MenuItemButton, SubmenuButton).

Visualização do impulsor

A equipe tem o prazer de anunciar que o novo mecanismo de renderização do Impeller está pronto para visualização no iOS no canal estável. Acreditamos que o desempenho do Impeller atenderá ou excederá o renderizador Skia para a maioria dos aplicativos e, quanto à fidelidade, o Impeller implementa todos, exceto um pequeno número de casos de canto raramente usados. Esperamos tornar o Impeller o renderizador padrão no iOS em uma versão estável futura, portanto, continue enviando comentários sobre o Impeller no GitHub.

Embora estejamos cada vez mais confiantes de que o Impeller no iOS atenderá às necessidades de renderização de quase todos os aplicativos Flutter existentes, ainda existem algumas lacunas na cobertura da API. O pequeno número de lacunas restantes está listado no wiki do Flutter. Os usuários também podem notar pequenas diferenças visuais na renderização entre o Skia e o Impeller. Essas pequenas diferenças podem ser bugs, portanto, não hesite em registrar problemas.

Nosso progresso no Impeller foi bastante acelerado pelas contribuições da comunidade. Em particular, os usuários do GitHub ColdPaleLight, guoguo338, JsouLiang e magicianA contribuíram com 37 de 291 (>12%) patches relacionados ao Impeller para esta versão. Obrigada!

Continuamos progredindo em um back-end Vulkan para o Impeller (com fallback para OpenGL em dispositivos mais antigos), mas o Impeller no Android ainda não está pronto para visualização. O suporte para Android está em desenvolvimento ativo e esperamos compartilhar mais sobre isso – com mais notícias sobre suporte para desktop e web – em versões futuras.

Acompanhe nosso progresso no quadro do projeto Impeller no GitHub.

 

Validação de lançamento do iOS

Quando você lança um aplicativo iOS, uma lista de verificação de configurações a serem atualizadas garante que seu aplicativo esteja pronto para envio à App Store.

O comando flutter build ipa agora valida algumas dessas configurações e informa se há alterações que devem ser feitas em seu aplicativo antes do lançamento.

 

Atualizações do DevTools

Nesta versão, há vários novos recursos de ferramentas e melhorias gerais para experimentar. A ferramenta de depuração DevTools Memory passou por uma revisão completa. Há três novas guias de recursos, Profile, Trace e Diff, que suportam todos os recursos de depuração de memória suportados anteriormente e adicionaram mais recursos para sua facilidade de depuração. Os novos recursos incluem a capacidade de analisar a alocação de memória atual para seu aplicativo por classe e tipo de memória, investigar quais caminhos de código estão alocando memória para um conjunto de classes em tempo de execução e diferenciar instantâneos de memória para entender o gerenciamento de memória entre dois pontos no tempo.

Todos esses novos recursos de memória foram documentados em docs.flutter.dev, então confira a documentação para mais detalhes.

A página Desempenho também possui alguns novos recursos notáveis. Uma nova guia de análise de quadro na parte superior da página de desempenho fornece informações sobre o quadro do Flutter selecionado. Os insights podem incluir sugestões sobre como rastrear partes caras do quadro Flutter com mais detalhes ou avisos sobre operações caras detectadas no quadro Flutter.

Estes são apenas alguns destaques, mas esta versão contém várias correções de bugs e melhorias além dos recursos mencionados aqui, incluindo algumas correções de bugs importantes para o Inspector, Network Profiler e CPU Profiler. Para obter uma lista mais detalhada de atualizações, confira as notas de versão das alterações do DevTools que foram incluídas no Flutter 3.7.

Notas de versão do Flutter DevTools 2.17.0
Notas de versão do Flutter DevTools 2.18.0
Notas de versão do Flutter DevTools 2.19.0
Notas de versão do Flutter DevTools 2.20.0

Menus de contexto personalizados

Agora você pode criar menus de contexto personalizados em qualquer lugar em um aplicativo Flutter. Você também pode usá-los para personalizar menus de contexto integrados.

Por exemplo, você pode adicionar um botão “Enviar e-mail” à barra de ferramentas de seleção de texto padrão que aparece quando o usuário seleciona um endereço de e-mail (código). Veja o parâmetro contextMenuBuilder, que foi adicionado aos widgets existentes que mostram um menu de contexto por padrão, como TextField. Você pode retornar qualquer widget que desejar do contextMenuBuilder, incluindo a modificação do menu de contexto adaptável à plataforma padrão.

Esse novo recurso também funciona fora da seleção de texto. Você pode, por exemplo, criar um widget de imagem que mostre um botão Salvar quando clicado com o botão direito do mouse ou pressionado longamente (código). Use ContextMenuController para exibir o menu de contexto padrão da plataforma atual, ou um personalizado, em qualquer lugar do seu aplicativo.

Veja um conjunto completo de exemplos no repositório de amostras do Flutter.

 

Widgets CupertinoListSection e CupertinoListTile

Graças aos esforços do usuário Github Campovski, Cupertino tem dois novos widgets, CupertinoListSection e CupertinoListTile, para mostrar uma lista rolável de widgets no estilo iOS. Eles são as versões Cupertino de ListView e ListTile em Material.

 

Melhorias na rolagem

Várias atualizações de rolagem chegaram com esta versão: polimento e refinamento para interações do trackpad, novos widgets como Scrollbars e DraggableScrollableSheet e manipulação aprimorada para seleção de texto em contextos de rolagem.

Notavelmente, os aplicativos MacOS agora terão maior fidelidade com a adição de uma nova física de rolagem para combinar com a plataforma de desktop.

Os novos widgets AnimatedGrid e SliverAnimatedGrid animam itens adicionados (ou removidos) de uma lista.

Por fim, corrigimos uma regressão no construtor do construtor de vários widgets de rolagem, como ListView. Durante a migração NNBD do framework Flutter, o itemBuilder, que permite aos usuários fornecer widgets sob demanda, foi migrado para um IndexedWidgetBuilder. Isso significava que o itemBuilder não poderia mais retornar null, que (no passado) poderia ser usado para indicar que o fim da lista havia sido atingido. Essa funcionalidade foi restaurada com NullableIndexedWidgetBuilder. Obrigado a @rrousselGit por perceber isso – anos após a migração – e enviar uma correção!

Ferramentas e documentos de internacionalização

O suporte à internacionalização foi totalmente reformulado! Reescrevemos completamente a ferramenta gen-l10n para suportar:

  • Erros de sintaxe descritiva.
  • Mensagens complexas envolvendo plurais aninhados/múltiplos, seleções e espaços reservados.

Para obter mais informações, consulte a página atualizada Internacionalizando aplicativos Flutter.

 

Melhorias na seleção global

SelectionArea agora suporta seleções de teclado. Você pode estender uma seleção existente com atalhos de teclado como shift+right.

 

BackGround isolates
Agora os Canais de Plataforma podem ser invocados de qualquer Isolado. Anteriormente, os usuários só podiam invocar canais de plataforma do isolamento principal fornecido pelo Flutter. Isso torna o trabalho com isolados e código de plataforma de host em plug-ins ou add-to-app melhor. Para obter mais informações, confira Escrever código específico da plataforma personalizada em flutter.dev e o artigo detalhado, Apresentando canais isolados em segundo plano, um artigo gratuito no Medium.

Text magnifier
A lupa que aparece durante a seleção de texto no Android e iOS agora funciona no Flutter. Isso é ativado imediatamente para todos os aplicativos com seleção de texto, mas se você quiser desativá-lo ou personalizá-lo, consulte a propriedade magnifierConfiguration.

 

Migração Swift para plugins

Com a Apple focando no Swift para suas próprias APIs, queríamos desenvolver referências para ajudar os desenvolvedores de plug-ins do Flutter a migrar ou criar novos plug-ins com o Swift. O plug-in quick_actions foi migrado de Objective-C para Swift e pode ser usado como uma demonstração das melhores práticas. Se você estiver interessado em nos ajudar a migrar plug-ins 1P, consulte a seção de migração Swift do wiki.

Recursos para desenvolvedores iOS

Publicamos vários novos recursos para desenvolvedores iOS, incluindo:

Descontinuação do código de bits

A partir do Xcode 14, o bitcode não é mais necessário para aplicativos watchOS e tvOS, e a App Store não aceita mais envios de bitcode do Xcode 14. Como tal, o suporte a bitcode foi removido do Flutter.

Por padrão, os aplicativos Flutter não têm bitcode ativado e não esperamos que isso afete muitos desenvolvedores. No entanto, se você ativou o bitcode manualmente em seu projeto Xcode, desative-o assim que atualizar para o Xcode 14. Você pode fazer isso abrindo ios/Runner.xcworkspace e defina Ativar Bitcode como Não. Os desenvolvedores de aplicativos adicionais devem desativar no projeto host Xcode.

Para saber mais sobre a distribuição de bitcode, confira a documentação da Apple.

iOS PlatformView BackdropFilter

Adicionamos a capacidade de visualizações nativas do iOS serem desfocadas quando renderizadas sob um widget Flutter desfocado, e os widgets UiKitView agora podem ser agrupados em um BackdropFilter.

Para obter mais informações, consulte o documento de design do iOS PlatformView BackdropFilter.

Gerenciamento de memória

Esta versão apresenta algumas melhorias no gerenciamento de memória que têm o efeito coletivo de reduzir a instabilidade causada por pausas na coleta de lixo, reduzindo a utilização da CPU devido à velocidade de alocação e threads de GC em segundo plano e reduzindo o consumo de memória.

Como exemplo, expandimos a prática existente de desalocar manualmente recursos nativos que suportam determinados objetos dart:ui Dart. Anteriormente, os recursos nativos seriam mantidos pelo mecanismo Flutter até que o lixo da VM Dart coletasse os objetos Dart. Por meio da análise dos aplicativos do usuário e de nossos próprios benchmarks, determinamos que essa estratégia em geral não faz o suficiente para evitar GCs inoportunos e uso excessivo de memória. Portanto, nesta versão, o mecanismo Flutter adiciona API para desalocar explicitamente os recursos nativos mantidos pelos objetos Vertices, Paragraph e ImageShader.

Em nossos benchmarks da estrutura Flutter migrada para esta API, essas melhorias reduziram os tempos de construção de quadros de 90% até mais de 30%, o que os usuários finais experimentarão como animações mais suaves com menos instabilidade.

Além disso, o mecanismo Flutter não registra mais o tamanho das imagens da GPU com a Dart VM. Como acima, essas imagens já foram desalocadas manualmente pela estrutura quando não eram mais necessárias, portanto, informar as políticas de GC do Dart sobre o tamanho da memória da GPU que suporta os objetos da pilha do Dart aumentava desnecessariamente a pressão da memória da pilha do Dart, acionando GCs inoportunas que não poderiam ter coletou qualquer memória adicional. Em linhas semelhantes, agora é política do mecanismo Flutter relatar à Dart VM apenas o tamanho superficial dos objetos nativos que suportam os objetos dart:ui Dart.

Em nossos benchmarks, essa alteração elimina o trabalho GC síncrono durante a construção de quadros quando um widget cria imagens residentes na GPU.

Nesta versão, o Flutter Engine também faz um trabalho melhor ao atualizar dinamicamente a Dart VM com informações sobre o estado do aplicativo Flutter. Em particular, o Flutter agora usa a API de estilo RAIL da Dart VM para entrar em um modo de baixa latência durante as animações de transição de rota. Durante esse modo de baixa latência, o alocador de memória da Dart VM prefere o crescimento da pilha em vez da coleta de lixo para evitar a interrupção das animações de transição com pausas de GC. Embora essa mudança não implique em nenhuma melhoria drástica de desempenho, planejamos expandir o uso desse modelo em versões futuras para eliminar ainda mais as pausas inoportunas do GC. Além disso, corrigimos erros na lógica que decide quando notificar a Dart VM de que o mecanismo Flutter está ocioso. A correção desses erros também evita instabilidade relacionada ao GC. Por fim, para aplicativos Flutter adicionados ao aplicativo, o mecanismo Flutter agora informa a Dart VM quando a exibição do Flutter não é mais exibida. Isso agora faz com que a VM Dart acione um GC principal final para o Isolate associado à visualização. Essa alteração reduz o consumo de memória do Flutter quando nenhuma visualização do Flutter está visível.

Desativando o macOS 10.11 a 10.13

Conforme anunciado anteriormente, o Flutter não suporta mais as versões do macOS 10.11 e 10.12. Desde esse anúncio, uma análise mais aprofundada revelou que a remoção do suporte para 10.13 também teria um impacto adicional limitado e ajudaria a equipe a simplificar bastante a base de código. Isso significa que os aplicativos criados em SDKs do Flutter estáveis com esta versão e posteriores não funcionarão mais nessas versões, e a versão mínima do macOS suportada pelo Flutter aumenta para 10.14 Mojave.

Como consequência, como todas as versões do iOS e macOS suportadas pelo Flutter incluem suporte a Metal, o back-end OpenGL foi removido dos incorporadores iOS e macOS. A remoção desses back-ends reduziu o tamanho compactado do mecanismo Flutter em cerca de 100 KB.

 

toImageSync

Esta versão adiciona os métodos Picture.toImageSync e Scene.toImageSync a dart:ui, análogo aos métodos assíncronos Picture.toImage e Scene.toImage.Picture.toImageSync retorna sincronizadamente um identificador para uma image de uma Picture, com a rasterização para o Imagem ocorrendo de forma assíncrona em segundo plano. A imagem é mantida como residente da GPU quando um contexto de GPU está disponível, o que significa que é mais rápido desenhar em comparação com as imagens produzidas por toImage. (As imagens produzidas por toImage também podem ser mantidas residentes na GPU, mas essa otimização ainda não foi implementada nesse cenário.)

As novas APIs toImageSync oferecem suporte a casos de uso, como:

  • Tirando rapidamente uma imagem cara para rasterizar para reutilização em vários quadros.
  • Aplicando filtros de passagem múltipla a uma imagem.
  • Aplicando shaders personalizados.

Como exemplo, a estrutura do Flutter agora usa essa API para melhorar o desempenho das transições de página no Android, o que reduz quase pela metade os tempos de rasterização de quadro, reduz a instabilidade e permite que a animação atinja 90/120 fps em dispositivos compatíveis com essas taxas de atualização.

Melhorias de suporte de sombreador personalizado

Esta versão inclui várias melhorias no suporte do Flutter para sombreadores de fragmentos personalizados. O Flutter SDK agora inclui um compilador de shader que compila os shaders GLSL listados no arquivo pubspec.yaml para o formato específico de back-end correto para a plataforma de destino. Além disso, shaders personalizados agora podem ser recarregados para um ciclo de desenvolvimento conveniente. Os shaders personalizados agora também são suportados pelos back-ends Skia e Impeller no iOS.

 

Recarregamento dinâmico do recurso de fonte

Anteriormente, adicionar novas fontes ao arquivo pubspec.yaml exigia a reconstrução do aplicativo para visualizá-las, ao contrário de outros tipos de ativos que podiam ser recarregados a quente. Agora as alterações no manifesto de fontes, incluindo adições de novas fontes, podem ser recarregadas a quente em um aplicativo.

Reduza a instabilidade da animação em dispositivos iOS

Graças às contribuições de código aberto do luckysmg, duas melhorias reduziram a instabilidade da animação no iOS. Em particular, a adição de um CADisplayLink fictício no thread principal durante os gestos agora força as atualizações na taxa de atualização máxima. Além disso, as animações de teclado agora definem a taxa de atualização do CADisplayLink para a mesma taxa de atualização usada pelo animador do mecanismo Flutter. Graças a essas mudanças, os usuários devem notar animações suaves de forma mais consistente em dispositivos iOS de 120 Hz.

Resumo

É um eufemismo dizer que o Flutter não seria a experiência incrível que é hoje sem sua comunidade de colaboradores talentosos e apaixonados. Enquanto continuamos esta jornada juntos, a equipe do Flutter no Google quer que todos saibam que não poderíamos fazer isso sem vocês. Obrigado!

O momento não está diminuindo, fique atento para futuras atualizações!