Registro do desenvolvimento do metrônomo
Ao testar a interface multilíngue do Flutter, encontramos “300 BPM” dividido em duas linhas
Testamos a exibição do SANGE Metronome combinando 12 idiomas, 6 tamanhos de tela e 3 escalas de texto. A quebra de linha de “300 BPM” e mensagens de erro longas motivaram correções na interface e a revisão das verificações dos testes automatizados.
Verificamos a exibição em telas pequenas e com texto ampliado no “SANGE Metronome – Prática simples de ritmo”, aplicativo que desenvolvemos de forma independente.
Um dos problemas encontrados foi o número em “300 BPM”, exibido nos favoritos, se dividir em “30” e “0”. O texto não ultrapassava a tela. Ainda assim, o valor do andamento ficava difícil de ler.
Foi necessário verificar separadamente se o layout não gerava exceções e se as informações necessárias podiam ser lidas.
Neste artigo, contamos quais problemas de exibição encontramos nos testes de widgets em 12 idiomas e nas verificações de tela no emulador Android, e como os incorporamos às correções e aos testes.

Um layout que funciona em japonês pode não funcionar da mesma forma em outros idiomas
A tela do metrônomo exibe não apenas o andamento, mas também batidas, nomes de ritmos, volume e nomes de favoritos. A tela de salvamento também precisa de campos de entrada, explicações de erros e botões Salvar e Cancelar.
Mesmo que um layout caiba em japonês, o tamanho dos rótulos muda com a tradução. Por exemplo, “12拍” em japonês e “12 Schläge” em alemão exigem larguras diferentes para o botão.
Ao aumentar o texto, os elementos dispostos lado a lado deixam de caber. Por isso, decidimos não apenas trocar o idioma, mas combinar tamanho de tela, escala de texto e tela exibida nas verificações.
Verificação automatizada com 12 idiomas, 6 tamanhos e 3 escalas de texto
Nos testes de widgets, combinamos as condições a seguir. Esses testes renderizam os componentes de interface do Flutter em um ambiente de teste para verificá-los.
| Dimensão da verificação | condições |
|---|---|
| Idioma | Japonês, inglês, espanhol, português do Brasil, alemão, francês, coreano, indonésio, vietnamita, tailandês, chinês tradicional e italiano |
| Tamanho lógico, orientação retrato | 320×568、360×640、360×800、393×873、412×915、432×960 |
| Escala do texto | 100%, 130% e 200% |
| Tela | Início, batidas, subdivisão rítmica, configurações, seleção de idioma, salvamento, gerenciamento de favoritos e lista de favoritos |
12 idiomas × 6 tamanhos × 3 escalas de texto × 8 telas = 1,728 condições
Os dados de teste incluíram 300 BPM, 12 batidas, semicolcheias, volume de 100% e três favoritos com nomes longos. Na tela de salvamento, também exibimos o erro de nome duplicado.
A escala do texto foi definida com TextScaler.linear. Os valores de 100%, 130% e 200% desta verificação são condições de ampliação linear e não reproduzem integralmente todas as formas de ampliação oferecidas pelas configurações do sistema de dispositivos reais.
Também coletamos imagens no emulador Android, em sete idiomas: alemão, francês, português do Brasil, indonésio, tailandês, vietnamita e japonês. Não testamos todas as combinações de tamanhos, escalas e idiomas. Verificamos os tamanhos de tela e as escalas em alemão; os outros seis idiomas foram verificados com configuração de 360×640 e escala de 130%.
No emulador, as barras do sistema reduzem a área disponível para o aplicativo. Além do tamanho configurado, registramos o tamanho lógico durante a renderização e as dimensões dentro da SafeArea.
Ajustar as colunas dos botões de batida para acomodar o texto
O primeiro problema encontrado foi o texto explicativo do andamento e a unidade das batidas ultrapassando a borda direita. O emulador Android também detectou RenderFlex overflow, o que exigiu uma revisão do layout.
Os botões de seleção de batidas também usavam quatro colunas fixas. Porém, com rótulos traduzidos mais longos ou uma escala de texto maior, essa quantidade de colunas não oferecia largura suficiente.
Passamos a medir os rótulos traduzidos com TextPainter e a determinar o número de colunas pela largura necessária, incluindo a escala do texto. Em condições estreitas, reduzimos as colunas e organizamos os botões verticalmente.


Na tela inicial, também revimos o layout que tentava acomodar nomes longos de ritmos em duas colunas estreitas, passando a empilhar batidas e ritmo quando necessário. Para evitar a divisão dos números das batidas 10 a 12, permitimos que o conjunto dos indicadores de batida se distribua por várias linhas.
A divisão de “300” nem sempre gera uma exceção
Ao examinar as imagens, encontramos o problema nos cartões de favoritos com configuração de 320×568 e escala de texto de 200%.
Como os cartões continuavam organizados em três colunas, o número “300” quebrava no meio. Mesmo que o texto caiba na área de exibição, dividi-lo em “30” e “0” dificulta a leitura do andamento.
Esse problema não pôde ser detectado apenas pela verificação de exceções de layout.
A correção ajustou o número de colunas dos cartões de favoritos de acordo com a escala do texto. Na tela pequena com escala de 200% desta verificação, passamos a uma coluna para evitar a divisão dos dígitos do andamento.

Junto com a correção, acrescentamos aos testes automatizados a verificação de que um BPM de três dígitos permaneça em uma linha. A seguir está um trecho dessa verificação.
for (var card = 0; card < 3; card++) {
final paragraph = tester.renderObject<RenderParagraph>(
find.text('300 BPM').at(card),
);
expect(
paragraph.getBoxesForSelection(
const TextSelection(baseOffset: 0, extentOffset: 3),
),
hasLength(1),
reason:
'$locale/$size/$scale favorite BPM must stay on one line',
);
}
Verificamos se o intervalo de caracteres correspondente a “300” ocupava uma única caixa de renderização. Nos testes completos, verificamos o BPM de cada um dos três favoritos e os números de batida de 1 a 12 na tela inicial.
Este método se aplica aos números renderizados com a mesma fonte nesta verificação. Ele não é um método geral para identificar quebras de linha em textos que misturam idiomas ou fontes diferentes.
Definir verificações concretas com base nas informações que queremos exibir. Um aprendizado desta rodada foi incorporar os problemas encontrados nas imagens aos testes automatizados, para detectá-los novamente em futuras alterações.
É possível ler a explicação do erro e acessar o botão Salvar?
Na tela de salvamento, também revimos o limite de linhas das mensagens de erro.
Antes, o texto era limitado a três linhas, mas traduções longas poderiam deixar de caber em telas estreitas com texto ampliado. Removemos esse limite para permitir a leitura da explicação completa com rolagem.
Os botões Salvar e Cancelar passaram a ficar empilhados em telas estreitas ou com texto grande. Também ajustamos o título e o botão de fechar do modal, assim como os nomes das configurações e seus valores selecionados, para reservar mais largura ao texto.

Também acrescentamos verificações durante a digitação. Nos testes de widgets, reservamos uma margem inferior de 280 pixels lógicos equivalente ao teclado e verificamos se, após a rolagem, o botão Salvar aparecia acima dessa área. Também verificamos se o limite de linhas não truncava as mensagens de erro.
No emulador Android, demos foco ao campo de entrada e verificamos o layout com o teclado aberto. Porém, os PNGs coletados nessa situação capturam apenas a tela Flutter: o próprio teclado do sistema não aparece. Registramos separadamente as imagens da exibição normal e da digitação.
Resultados após as correções e alcance da verificação
Estes são os resultados da verificação realizada em 30 de outubro de 2026.
| Artigo | Resultado |
|---|---|
| Testes de widgets de exibição | Nenhuma exceção de layout em 1,728 condições. As verificações de divisão de números, truncamento de mensagens de erro e acesso ao botão Salvar também passaram nas telas correspondentes |
| Todos os testes Flutter | 121 testes aprovados |
| Análise estática | Nenhum problema apontado |
| Condições de tela no emulador Android | 280 condições. Em cada execução, layoutErrors foi 0 |
| PNGs coletados | 478 imagens, incluindo estados após a rolagem e durante a digitação |
1,728 é o número de combinações de condições de exibição, enquanto 121 é o total de testes Flutter executados. Como os testes verificam repetidamente várias condições de exibição, esses números têm significados diferentes.
O número 478 corresponde aos PNGs coletados. Não atribuímos um resultado visual individual de aprovação ou reprovação a todas as imagens; selecionamos telas principais para verificar caracteres cortados ou sobrepostos, números divididos e a exibição após a rolagem. Nas telas principais verificadas em tailandês e vietnamita, não observamos quadrados de caracteres ausentes nem sobreposição de texto.
Além dos seis tamanhos sintéticos, usamos seis configurações de exibição no emulador: Galaxy A16 5G, A06 4G, S24+, S23, Redmi 14C 4G e Pixel 9. Preparamos 30 configurações específicas de modelos, mas executamos seis delas nesta rodada.
Aplicamos resoluções e densidades aproximadas para teste ao mesmo emulador Android 14. Não reproduzimos sistemas personalizados de fabricantes, fontes ou recortes de câmera, nem testamos 30 modelos em dispositivos reais. Os testes Flutter foram executados no Windows; também não executamos a comparação golden de pixels para Linux nesta rodada.
Este registro trata da verificação da exibição. Os resultados de renderização, foco no campo de entrada e rolagem não comprovam o sucesso da reprodução de áudio nem do processo de salvamento.
O que continuar verificando nas próximas alterações de interface
Esta verificação tornou mais concretos os itens que queremos manter nos testes de exibição.
- Não dividir no meio números como andamento e índices de batida.
- Permitir a leitura completa das explicações de erro.
- Manter os botões necessários acessíveis com texto ampliado e durante a digitação.
Ao ajustar o número de colunas ao tamanho do texto e às traduções, e usar disposição vertical e rolagem, reservamos espaço para as informações e operações necessárias.
Repetir as condições nos testes automatizados e incorporar às verificações os problemas percebidos nas imagens renderizadas. Ao manter esse fluxo, poderemos verificar se os problemas encontrados nesta rodada reaparecem nas próximas alterações da interface.