Desenvolver para diferentes tamanhos de tela

Seu app precisa funcionar bem em dispositivos Wear OS de todos os tamanhos, aproveitando o espaço extra quando disponível, e ainda ter uma ótima aparência em telas menores. Este guia fornece recomendações para alcançar essa experiência do usuário.

Para saber mais sobre os princípios de design para layouts adaptáveis, leia as orientações de design.

Criar layouts responsivos usando o Horologist

Os layouts precisam ter margens baseadas em porcentagem. Como o Compose funciona por padrão em valores absolutos, use componentes da Biblioteca Horologist, que tem os seguintes recursos:

  • As margens horizontais são definidas corretamente com base em uma porcentagem do tamanho da tela do dispositivo.
  • O espaçamento superior e inferior foi definido corretamente. Isso apresenta desafios específicos, porque o espaçamento recomendado nas partes superior e inferior pode depender dos componentes usados. Por exemplo, um Chip precisa ter um espaçamento diferente para um componente Text quando usado em uma lista.
  • As margens do TimeText foram definidas corretamente.

O snippet de código abaixo usa a versão do layout ScalingLazyColumn do Horologist para criar conteúdo com uma ótima aparência em vários tamanhos de tela do Wear OS:

import com.google.android.horologist.compose.layout.ScalingLazyColumn

val columnState = rememberResponsiveColumnState(
    contentPadding = ScalingLazyColumnDefaults.padding(
        first = ItemType.Text,
        last = ItemType.SingleButton
    )
)

ScreenScaffold(scrollState = columnState) {
    ScalingLazyColumn(
        columnState = columnState,
        modifier = Modifier.fillMaxSize()
    ) {
        item {
            ResponsiveListHeader(contentPadding = firstItemPadding()) {
                Text(text = "Header")
            }
        }
        // ... other items
        item {
            Button(...)
        }
    }
}

Este exemplo também demonstra ScreenScaffold]3 e AppScaffold. Elas coordenam entre o app e as telas individuais (rotas de navegação) para garantir o comportamento de rolagem e o posicionamento de TimeText corretos.

Para o padding superior e inferior, observe também o seguinte:

  • A especificação do primeiro e do último ItemType para determinar o padding correto.
  • O uso de ResponsiveListHeader para o primeiro item na lista, porque os cabeçalhos Text não podem ter padding.

As especificações completas podem ser encontradas nos kits de design do Figma. Para mais detalhes e exemplos, consulte:

  • A biblioteca Horologist (link em inglês) fornece componentes para ajudar a criar apps otimizados e diferenciados para o Wear OS.
  • O exemplo do ComposeStarter (link em inglês): um exemplo que mostra os princípios descritos neste guia.
  • O exemplo do JetCaster (link em inglês): um exemplo mais complexo de criação de um app para funcionar com diferentes tamanhos de tela, usando a biblioteca Horologist.

Usar layouts de rolagem no app

Use um layout de rolagem, conforme mostrado anteriormente nesta página, como a escolha padrão ao implementar suas telas. Isso permite que os usuários acessem os componentes do app independentemente das preferências de exibição ou do tamanho da tela do dispositivo Wear OS.

O efeito de diferentes tamanhos de dispositivo e dimensionamento de fonte

O efeito de diferentes tamanhos de dispositivo e dimensionamento de fonte.

Caixas de diálogo

As caixas de diálogo também precisam ser roláveis, a menos que haja um bom motivo para não fazer isso. O componente ResponsiveDialog, fornecido pelo Horologist, adiciona o seguinte:

  • Rolagem por padrão.
  • Corrigir margens baseadas em porcentagem.
  • Botões que ajustam a largura onde houver espaço, para aumentar o área de toque.
Comportamento adaptável de diálogo no Horologist

Caixas de diálogo responsivas, oferecendo rolagem por padrão e botões que se adaptam ao espaço disponível.

As telas personalizadas podem exigir layouts sem rolagem

Algumas telas ainda podem ser adequadas para layouts sem rolagem. Vários exemplos incluem a tela principal do player em um app de música e a tela de treino em um app fitness.

Nesses casos, consulte a orientação canônica fornecida nos kits de design do Figma e implemente um design responsivo ao tamanho da tela, usando as margens corretas.

Ofereça experiências diferenciadas usando pontos de interrupção

Em telas maiores, você pode incluir mais conteúdos e recursos. Para implementar esse tipo de experiência diferenciada, use pontos de interrupção de tamanho de tela, mostrando um layout diferente quando o tamanho da tela exceder 225 dp:

const val LARGE_DISPLAY_BREAKPOINT = 225

@Composable
fun isLargeDisplay() = LocalConfiguration.current.screenWidthDp >= LARGE_DISPLAY_BREAKPOINT

// ... use in your Composables:
if (isLargeDisplay()) {
    // Show additional content.
} else {
    // Show content only for smaller displays.
}

As orientações de design ilustram mais essas oportunidades.

Testar combinações de tamanhos de tela e fonte usando visualizações

As visualizações do Compose ajudam você a desenvolver para vários tamanhos de tela do Wear OS. Use as definições de dispositivos e de visualização do dimensionamento de fonte para ver o seguinte:

  • A aparência das telas nos extremos de tamanho, por exemplo, a maior fonte pareada com a menor tela.
  • Como sua experiência diferenciada se comporta nos pontos de interrupção.

Implemente visualizações usando WearPreviewDevices e WearPreviewFontScales para todas as telas do seu app.

@WearPreviewDevices
@WearPreviewFontScales
@Composable
fun ListScreenPreview() {
    ListScreen()
}

Teste de captura de tela

Além do teste de visualização, os testes de captura de tela permitem testar usando uma variedade de tamanhos de hardware existentes. Isso é particularmente útil quando esses dispositivos podem não estar disponíveis imediatamente para você e o problema pode não se apresentar em outros tamanhos de tela.

O teste de captura de tela também ajuda a identificar regressões em locais específicos da base de código.

Nossas amostras usam o Roborazzi para testes de captura de tela:

  1. Configure seus arquivos build.gradle do projeto e do app para usar o Roborazzi.
  2. Crie um teste de captura de tela para cada tela do app. Por exemplo, no exemplo ComposeStarter, um teste para o GreetingScreen é implementado em GreetingScreenTest:
@RunWith(ParameterizedRobolectricTestRunner::class)
class GreetingScreenTest(override val device: WearDevice) : WearScreenshotTest() {
    override val tolerance = 0.02f

    @Test
    fun greetingScreenTest() = runTest {
        AppScaffold(
            timeText = { ResponsiveTimeText(timeSource = FixedTimeSource) }
        ) {
            GreetingScreen(greetingName = "screenshot", 
        }
    }

    companion object {
        @JvmStatic
        @ParameterizedRobolectricTestRunner.Parameters
        fun devices() = WearDevice.entries
    }
}

Alguns pontos importantes a serem observados:

  • O FixedTimeSource permite gerar capturas de tela em que o TimeText não varia e faz com que os testes falhem acidentalmente.
  • O WearDevice.entries contém definições dos dispositivos Wear OS mais usados para que os testes sejam executados em um intervalo representativo de tamanhos de tela.

Gerar imagens douradas

Para gerar imagens para suas telas, execute o seguinte comando em um terminal:

./gradlew recordRoborazziDebug

Verificar imagens

Para verificar as alterações em relação às imagens atuais, execute o seguinte comando em um terminal:

./gradlew verifyRoborazziDebug

Para ver um exemplo completo de testes de captura de tela, consulte o exemplo do ComposeStarter.