Codelab sobre o Compose para Wear OS

1. Introdução

11ba5a682f1ffca3.png

Com o Compose para Wear OS, você pode usar o que aprendeu sobre a criação de apps com o Jetpack Compose e criar apps para wearables.

Com suporte integrado para o Material You, o Compose para Wear OS simplifica e acelera o desenvolvimento da interface e ajuda você a criar apps incríveis usando menos código.

Para concluir este codelab, é necessário que você tenha algum conhecimento sobre o Compose, mas você não precisa ser especialista.

Você vai criar vários elementos combináveis (simples e complexos) específicos do Wear e, no final, vai começar a criar seus próprios apps para Wear OS. Vamos começar!

O que você vai aprender

  • Semelhanças/diferenças entre sua experiência anterior com o Compose
  • Elementos combináveis simples e como funcionam no Wear OS
  • Elementos combináveis específicos do Wear OS
  • O elemento LazyColumn do Wear OS (ScalingLazyColumn)
  • A versão do elemento Scaffold do Wear OS

O que você vai criar

Você vai criar um app simples que mostra uma lista rolável de elementos otimizados para Wear OS.

Como você vai usar o Scaffold, também terá um texto curvado mostrando o horário na parte de cima da tela, uma vinheta e um indicador de rolagem na lateral do dispositivo.

Confira como ele vai ficar quando você terminar o codelab:

31cb08c0fa035400.gif

Pré-requisitos

2. Etapas da configuração

Nesta etapa, você vai configurar seu ambiente e fazer o download do projeto inicial.

O que é necessário

  • Versão estável mais recente do Android Studio.
  • Dispositivo ou emulador do Wear OS. (Novo usuário? Veja aqui como configurar esse recurso.)

Fazer o download do código

Se você tiver o git instalado, execute o comando abaixo para clonar o código deste repositório. Para verificar se o git está instalado, digite git --version no terminal ou na linha de comando e verifique se ele é executado corretamente.

git clone https://github.com/android/codelab-compose-for-wear-os.git
cd compose-for-wear-os

Caso você não tenha o git, clique no botão abaixo para fazer o download de todo o código para este codelab:

Você pode executar qualquer um dos módulos no Android Studio quando quiser mudando a configuração de execução na barra de ferramentas.

400c194c8948c952.png

Abrir o projeto no Android Studio

  1. Na janela "Welcome to Android Studio", selecione 61d0a4432ef6d396.png Open an Existing Project.
  2. Selecione a pasta [Download Location]
  3. Depois que o Android Studio importar o projeto, teste se você pode executar os módulos start e finished em um emulador ou dispositivo físico do Wear OS.
  4. O módulo start será parecido com a captura de tela abaixo. É nele que você vai fazer todo o trabalho.

c82b07a089099c4f.png

Conhecer o código inicial

  • build.gradle contém uma configuração básica de app. Ele inclui as dependências necessárias a fim de criar um app combinável para Wear OS. Abordaremos as semelhanças e diferenças entre o Jetpack Compose e a versão para Wear OS.
  • O main > AndroidManifest.xml inclui os elementos necessários para criar um app para Wear OS. Esses elementos são os mesmos utilizados em apps que não usam o Compose e são parecidos com os de apps para dispositivos móveis. Por isso, não revisaremos esse ponto.
  • A pasta main > theme/ contém os arquivos Color, Type e Theme usados pelo Compose para o tema.
  • O main > MainActivity.kt contém um código boilerplate para criar um app com o Compose, além dos elementos combináveis de nível superior do app, como Scaffold e ScalingLazyList.
  • O main > ReusableComponents.kt contém funções para a maioria dos elementos específicos do Wear que vamos criar. Faremos grande parte do nosso trabalho nesse arquivo.

3. Analisar as dependências

A maioria das mudanças de dependência relacionadas ao Wear são feitas nas primeiras camadas de arquitetura, destacadas em vermelho abaixo.

d64d9c262a79271.png

Isso significa que muitas das dependências que você já usa com o Jetpack Compose não mudam ao criar um app para Wear OS. Por exemplo, as dependências de interface, ambiente de execução, compilador e animação permanecerão as mesmas.

No entanto, você vai precisar usar as bibliotecas Material, Foundation e Navigation do Wear OS, que são diferentes das usadas anteriormente.

Veja abaixo uma comparação que ajuda a esclarecer as diferenças:

Dependência do Wear OS (androidx.wear.*)

Comparação

Dependência padrão (androidx.*)

androidx.wear.compose:compose-material

em vez de

androidx.compose.material:material

androidx.wear.compose:compose-navigation

em vez de

androidx.navigation:navigation-compose

androidx.wear.compose:compose-foundation

além de

androidx.compose.foundation:foundation

androidx.wear.compose:compose-ui-tooling

além de

androidx.compose.ui:ui-tooling-preview

1. Os desenvolvedores podem continuar usando outras bibliotecas relacionadas ao Material, como a ondulação e os ícones do Material estendidos com a biblioteca Wear Compose Material.

Abra o build.gradle e procure "TODO: Review Dependencies" no módulo start. Essa etapa serve apenas para revisar as dependências. Você ainda não adicionará nenhum código.

start/build.gradle:

// TODO: Review Dependencies
// General Compose dependencies
implementation "androidx.activity:activity-compose:$activity_compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation "androidx.compose.foundation:foundation:$compose_version"
implementation "androidx.compose.material:material-icons-extended:$compose_version"

// Compose for Wear OS Dependencies
implementation "androidx.wear.compose:compose-material:$wear_compose_version"

// Foundation is additive, so you can use the standard version in your Wear OS app.
implementation "androidx.wear.compose:compose-foundation:$wear_compose_version"

// Compose preview annotations for Wear OS.
implementation "androidx.wear.compose:compose-ui-tooling:$wear_compose_version"

Você reconhecerá várias das dependências gerais do Compose, então elas não serão abordadas.

Vamos às dependências do Wear OS.

Conforme descrito anteriormente, apenas a versão específica para Wear OS do material (androidx.wear.compose:compose-material) é incluída. Isso significa que você não verá nem incluirá androidx.compose.material:material no projeto.

É importante destacar que você pode usar outras bibliotecas do Material com o Wear Material. Neste codelab, isso será feito pela inclusão de androidx.compose.material:material-icons-extended.

Por fim, incluímos a biblioteca foundation do Wear para Compose (androidx.wear.compose:compose-foundation). Essa biblioteca é aditiva e pode ser usada com a foundation padrão que você já usou antes. É provável que você já tenha percebido que nós a incluímos nas dependências gerais do Compose.

Agora que entendemos as dependências, podemos tratar do app principal.

4. Analisar a MainActivity

Realizaremos todo o nosso trabalho no módulo

start

Por isso, todos os arquivos que você abrir precisarão estar lá.

Para começar, abra o arquivo MainActivity no módulo start.

Essa é uma classe muito simples que estende a ComponentActivity e usa setContent { WearApp() } para criar a IU.

Por já ter certo conhecimento sobre o Compose, você provavelmente conhece esse processo. Estamos apenas configurando a interface.

Role a tela para baixo até a função combinável WearApp(). Antes de abordarmos o código em si, observe que há vários comentários "TODO" espalhados por ele. Cada um representa uma etapa deste codelab. Você pode ignorar esse comentários por enquanto.

O código vai ser semelhante a este:

Código na função WearApp():

WearAppTheme {
    // TODO: Swap to ScalingLazyListState
    val listState = rememberLazyListState()

    /* *************************** Part 4: Wear OS Scaffold *************************** */
    // TODO (Start): Create a Scaffold (Wear Version)

        // Modifiers used by our Wear composables.
        val contentModifier = Modifier.fillMaxWidth().padding(bottom = 8.dp)
        val iconModifier = Modifier.size(24.dp).wrapContentSize(align = Alignment.Center)

        /* *************************** Part 3: ScalingLazyColumn *************************** */
        // TODO: Create a ScalingLazyColumn (Wear's version of LazyColumn)
        LazyColumn(
            modifier = Modifier.fillMaxSize(),
            contentPadding = PaddingValues(
                top = 32.dp,
                start = 8.dp,
                end = 8.dp,
                bottom = 32.dp
            ),
            verticalArrangement = Arrangement.Center,
            state = listState
        ) {

            // TODO: Remove item; for beginning only.
            item { StartOnlyTextComposables() }

            /* ******************* Part 1: Simple composables ******************* */
            item { ButtonExample(contentModifier, iconModifier) }
            item { TextExample(contentModifier) }
            item { CardExample(contentModifier, iconModifier) }

            /* ********************* Part 2: Wear unique composables ********************* */
            item { ChipExample(contentModifier, iconModifier) }
            item { ToggleChipExample(contentModifier) }
        }

    // TODO (End): Create a Scaffold (Wear Version)

}

Comece definindo o tema WearAppTheme { }. Isso é feito exatamente da mesma forma que você já fez antes, ou seja, definindo um MaterialTheme com cores, tipografias e formas.

No caso do Wear OS, geralmente recomendamos usar as formas padrão do Material Wear, que são otimizadas para dispositivos redondos e não redondos. Por isso, ao analisar o arquivo theme/Theme.kt, você vai ver que não modificamos as formas.

Se quiser, pode abrir o theme/Theme.kt para analisar melhor, mas os elementos são iguais aos anteriores.

Depois, criaremos alguns modificadores para os elementos combináveis do Wear que vamos desenvolver. Assim, eles não precisam ser especificados todas as vezes. Basicamente, centralizamos o conteúdo e adicionamos padding.

Em seguida, criamos uma LazyColumn que é usada a fim de produzir uma lista de rolagem vertical para muitos itens, como você fez anteriormente.

Código:

item { StartOnlyTextComposables() }

/* ******************* Part 1: Simple composables ******************* */
item { ButtonExample(contentModifier, iconModifier) }
item { TextExample(contentModifier) }
item { CardExample(contentModifier, iconModifier) }

/* ********************* Part 2: Wear unique composables ********************* */
item { ChipExample(contentModifier, iconModifier) }
item { ToggleChipExample(contentModifier) }

Com relação aos itens em si, apenas StartOnlyTextComposables() produz uma interface. O restante vai ser preenchido ao longo deste codelab.

Essas funções estão no arquivo ReusableComponents.kt, que vai ser abordado na próxima seção.

Vamos começar a usar o Compose para Wear OS.

5. Adicionar elementos simples combináveis

Começaremos com três elementos (Button, Text e Card) que você provavelmente já conhece.

Primeiro, removeremos o elemento Hello World.

Pesquise "TODO: Remove item" e apague o comentário e a linha abaixo dele:

Etapa 1

// TODO: Remove item; for beginning only.
item { StartOnlyTextComposables() }

Agora, vamos adicionar o primeiro elemento combinável.

Criar um botão combinável

Abra o ReusableComponents.kt no módulo start, pesquise "TODO: Create a Button Composable" e substitua o método de composição atual pelo código a seguir.

Etapa 2

// TODO: Create a Button Composable (with a Row to center)
@Composable
fun ButtonExample(
    modifier: Modifier = Modifier,
    iconModifier: Modifier = Modifier
) {
    Row(
        modifier = modifier,
        horizontalArrangement = Arrangement.Center
    ) {
        // Button
        Button(
            modifier = Modifier.size(ButtonDefaults.LargeButtonSize),
            onClick = { /* ... */ },
        ) {
            Icon(
                imageVector = Icons.Rounded.Phone,
                contentDescription = "triggers phone action",
                modifier = iconModifier
            )
        }
    }
}

Agora, a função combinável ButtonExample(), onde o código se encontra, vai gerar um botão centralizado.

Vamos analisar o código:

A função Row só é usada aqui para centralizar o elemento Button na tela redonda. Note que fazemos isso aplicando o modificador que criamos na MainActivity e o transmitindo para essa função. Ao usar a rolagem em uma tela circular mais tarde, precisamos garantir que o conteúdo não seja cortado, e é por isso que ele é centralizado.

Em seguida, criamos o Button. O código é o mesmo usado anteriormente para um botão em apps, mas neste caso, usamos ButtonDefault.LargeButtonSize. É importante que você use esses tamanhos predefinidos, porque eles são otimizados para dispositivos Wear OS.

Depois, definimos o evento de clique como uma lambda vazia. Em nosso caso, como os elementos combinável servem apenas para demonstração, não precisamos disso. No entanto, a comunicação com um ViewModel, por exemplo, seria necessária em um app real para executar a lógica de negócios.

Em seguida, definimos um ícone dentro do botão. O código é o mesmo usado antes para o Icon. O ícone também é derivado da biblioteca androidx.compose.material:material-icons-extended.

Por fim, definimos o modificador configurado anteriormente para os ícones.

Se você executar o app, o resultado vai ficar assim:

c9b981101ae653db.png

É provável que você já tenha programado códigos como esse antes, o que é ótimo. A diferença é que agora você tem um botão otimizado para o Wear OS.

É muito simples. Vamos analisar outro caso.

Criar um elemento combinável de texto

No ReusableComponents.kt, pesquise "TODO: Create a Text Composable" e substitua o método de composição atual pelo código abaixo.

Etapa 3

// TODO: Create a Text Composable
@Composable
fun TextExample(modifier: Modifier = Modifier) {
    Text(
        modifier = modifier,
        textAlign = TextAlign.Center,
        color = MaterialTheme.colors.primary,
        text = stringResource(R.string.device_shape)
    )
}

Vamos criar o elemento combinável Text, definir o modificador, alinhar o texto, definir uma cor e, por fim, configurar o texto usando um recurso de string.

Para desenvolvedores do Compose, os elementos combináveis de texto são bastante conhecidos e o código é idêntico ao usado antes.

Este é o resultado:

b33172e992d1ea3e.png

A função combinável TextExample(), em que colocamos nosso código, agora gera um elemento combinável de texto com a nossa cor principal do Material Design.

A string é extraída do arquivo res/values/strings.xml. Na pasta res/values, você encontrará dois arquivos de recurso strings.xml.

O Wear OS oferece recursos de string para dispositivos redondos e não redondos. Portanto, se executarmos esse código em um emulador quadrado, a string vai mudar:

2e7b20dbfbd23350.png

Até aqui, tudo bem. Vamos analisar o último elemento combinável, o Card.

Criar um card combinável

No ReusableComponents.kt, pesquise "TODO: Create a Card" e substitua o método combinável atual pelo código abaixo.

Etapa 4

// TODO: Create a Card (specifically, an AppCard) Composable
@Composable
fun CardExample(
    modifier: Modifier = Modifier,
    iconModifier: Modifier = Modifier
) {
    AppCard(
        modifier = modifier,
        appImage = {
            Icon(
                imageVector = Icons.Rounded.Message,
                contentDescription = "triggers open message action",
                modifier = iconModifier
            )
        },
        appName = { Text("Messages") },
        time = { Text("12m") },
        title = { Text("Kim Green") },
        onClick = { /* ... */ }
    ) {
        Text("On my way!")
    }
}

O Wear é um pouco diferente aqui, porque há dois cards principais: AppCard e TitleCard.

Em nosso caso, queremos mostrar um Icon no card, então vamos usar o AppCard, já que o TitleCard tem menos slots. Consulte o guia Cards para saber mais.

Vamos criar o elemento combinável AppCard, definir o modificador dele, adicionar um Icon, incluir vários parâmetros combináveis Text (um para cada espaço diferente no card) e, por fim, definir o texto principal.

Este é o resultado:

1fc761252ac5b466.png

Você provavelmente percebeu que, para esses elementos combináveis, o código do Compose é praticamente o mesmo usado antes, o que é ótimo. Isso significa que você pode colocar em prática todo o conhecimento que já adquiriu.

Agora, vamos analisar alguns novos elementos combináveis.

6. Adicionar elementos combináveis exclusivos para Wear OS

Nesta seção, abordaremos os elementos Chip e ToggleChip.

Criar um ícone combinável

Os ícones são especificados nas diretrizes do Material Design (link em inglês), mas não há uma função combinável na biblioteca padrão do Material.

O objetivo deles é permitir uma ação rápida, executada com um único toque. Isso é muito útil para um dispositivo Wear, que tem espaço de tela limitado.

Para você ter uma ideia do que pode ser criado, confira algumas variações da função combinável Chip:

Vamos criar o código.

No ReusableComponents.kt, pesquise "TODO: Create a Chip" e substitua o método combinável atual pelo código abaixo.

Etapa 5

// TODO: Create a Chip Composable
@Composable
fun ChipExample(
    modifier: Modifier = Modifier,
    iconModifier: Modifier = Modifier
) {
    Chip(
        modifier = modifier,
        onClick = { /* ... */ },
        label = {
            Text(
                text = "5 minute Meditation",
                maxLines = 1,
                overflow = TextOverflow.Ellipsis
            )
        },
        icon = {
            Icon(
                imageVector = Icons.Rounded.SelfImprovement,
                contentDescription = "triggers meditation action",
                modifier = iconModifier
            )
        },
    )
}

Como o elemento combinável Chip usa muitos dos mesmos parâmetros utilizados em outros elementos (modificador e onClick), não precisamos relembrar esses pontos.

Ele também tem um rótulo, para o qual criaremos um ícone e um elemento combinável Text.

O código do Icon precisa ser exatamente igual ao que você viu em outros elementos combináveis. A diferença é que, para esse caso, extraímos o ícone Self Improvement da biblioteca androidx.compose.material:material-icons-extended.

Vamos conferir o resultado. Não se esqueça de rolar a tela para baixo:

d97151e85e9a1e03.png

Agora, vamos abordar a variação do Toggle, o elemento combinável ToggleChip.

Criar um elemento combinável ToggleChip

O ToggleChip é semelhante a um Chip, mas permite que o usuário interaja com um botão de opção, de alternância ou uma caixa de seleção.

No ReusableComponents.kt, pesquise "TODO: Create a ToggleChip" e substitua o método combinável atual pelo código abaixo.

Etapa 6

// TODO: Create a ToggleChip Composable
@Composable
fun ToggleChipExample(modifier: Modifier = Modifier) {
    var checked by remember { mutableStateOf(true) }
    ToggleChip(
        modifier = modifier,
        checked = checked,
        toggleControl = {
            Switch(
                checked = checked,
                modifier = Modifier.semantics {
                    this.contentDescription = if (checked) "On" else "Off"
                }
            )
        },
        onCheckedChange = {
            checked = it
        },
        label = {
            Text(
                text = "Sound",
                maxLines = 1,
                overflow = TextOverflow.Ellipsis
            )
        }
    )
}

Agora, a função combinável ToggleChipExample(), em que esse código se encontra, gera um ToggleChip usando um botão de alternância, em vez de uma caixa de seleção ou um botão de opção.

Primeiro, vamos criar um MutableState. Não fizemos isso nas outras funções porque estamos fazendo apenas demonstrações da interface para apresentar as possibilidades do Wear OS.

Em um app normal, é recomendável transmitir o estado marcado e a lambda para processar o toque. Desse modo, o elemento pode ficar sem estado (Saiba mais).

Estamos usando um caso simples apenas para mostrar como o ToggleChip funciona com a alternância, mesmo sem causar nenhuma mudança de estado.

Em seguida, vamos definir o modificador, o estado marcado e o controle de alternância para mostrar a chave que queremos.

Vamos criar uma lambda para mudar o estado e, por fim, definir o marcador com um elemento combinável Text e configurar alguns parâmetros básicos.

Este é o resultado:

ea1a76abd54877b.png

Agora você já aprendeu sobre vários elementos específicos do Wear OS. Como mencionado, a maior parte do código é quase igual ao código usado antes.

Vamos para algo um pouco mais avançado.

7. Migrar para o ScalingLazyColumn

É provável que você já tenha usado o elemento LazyColumn nos seus apps para dispositivos móveis para produzir uma lista de rolagem vertical.

Como dispositivos redondos são menores nas partes de cima e de baixo, há menos espaço para mostrar itens. Por isso, o Wear OS tem uma versão própria do LazyColumn, que oferece melhor suporte para esses dispositivos.

O ScalingLazyColumn estende o LazyColumn para que esse elemento ofereça suporte para o escalonamento e a transparência na parte de cima e de baixo da tela, deixando o conteúdo mais legível para o usuário.

Veja uma demonstração:

198ee8e8fa799f08.gif

Observe que o item é redimensionado para o tamanho original à medida que se aproxima do centro e, ao se afastar, diminui novamente e fica mais transparente.

Confira um exemplo mais concreto de um app:

a5a83ab2e5d5230f.gif

Descobrimos que isso é muito útil para facilitar a leitura.

Agora que você sabe como a ScalingLazyColumn funciona na prática, vamos começar a converter nossa LazyColumn.

Converter para um ScalingLazyListState

No MainActivity.kt, pesquise "TODO: Swap to ScalingLazyListState" e substitua o comentário e a linha abaixo do elemento pelo código a seguir.

Etapa 7

// TODO: Swap to ScalingLazyListState
val listState = rememberScalingLazyListState()

Os nomes são quase idênticos, exceto pelo trecho "Scaling". Assim como o LazyListState processa o estado de uma LazyColumn, o ScalingLazyListState processa o estado de uma ScalingLazyColumn.

Converter para um ScalingLazyColumn

Agora, vamos trocar para o elemento ScalingLazyColumn.

No arquivo MainActivity.kt, pesquise "TODO: Swap a ScalingLazyColumn". Primeiro, substitua LazyColumn por ScalingLazyColumn.

Em seguida, remova contentPadding e verticalArrangement. O ScalingLazyColumn já oferece configurações padrão que garantem um efeito visual melhor, já que a maior parte da janela de visualização vai ser preenchida com itens de lista. Em muitos casos, os parâmetros padrão são suficientes. Se o cabeçalho estiver na parte de cima da tela, recomendamos que você o coloque em ListHeader como o primeiro item. Caso contrário, considere definir autoCentering com o itemIndex como 0, o que vai proporcionar padding suficiente para o primeiro item.

Etapa 8

// TODO: Swap a ScalingLazyColumn (Wear's version of LazyColumn)
ScalingLazyColumn(
    modifier = Modifier.fillMaxSize(),
    autoCentering = AutoCenteringParams(itemIndex = 0),
    state = listState

Pronto! Este é o resultado:

5c25062081307944.png

Você vai notar que o conteúdo é redimensionado e a transparência é ajustada na parte de cima e de baixo da tela à medida que o usuário usa a rolagem, exigindo pouco trabalho para migração.

Esse processo pode ser visto claramente nos elementos de meditação ao rolar a tela para cima e para baixo.

Agora, vamos ao último tema: o Scaffold do Wear OS.

8. Adicionar um Scaffold

O Scaffold oferece uma estrutura de layout para ajudar você a organizar as telas em padrões comuns, assim como acontece em apps para dispositivos móveis. Contudo, diferente de barras de apps, botões de ação flutuante, gavetas ou outros elementos específicos para dispositivos móveis, ele tem suporte para quatro layouts específicos do Wear com componentes de nível superior: horário, vinheta, indicador de rolagem/posição e indicador de página.

Além disso, ele funciona em dispositivos redondos e em outros formatos.

Os elementos ficam assim:

TimeText

Vignette

PositionIndicator

PageIndicator

Vamos analisar os três primeiros componentes em detalhes, mas antes vamos implementar o Scaffold.

Adicionar um Scaffold

Vamos adicionar o código boilerplate do Scaffold.

Encontre o comentário TODO (Start): Create a Scaffold (Wear Version) e adicione este código abaixo dele.

Etapa 9

// TODO (Start): Create a Scaffold (Wear Version)
Scaffold(
    timeText = { },
    vignette = { },
    positionIndicator = { }
) {

Explicaremos cada um desses parâmetros em sequência nas próximas etapas. Por enquanto, ainda não estamos gerando nenhuma interface.

Agora, adicione a chave de fechamento no local certo. Encontre o comentário TODO (End): Create a Scaffold (Wear Version) e adicione a chave:

Etapa 10

// TODO (End): Create a Scaffold (Wear Version)
}

Primeiro, vamos executar o app. Você vai encontrar algo como:

ff554156bbe03abb.png

Note que o comportamento continua praticamente igual mesmo depois de adicionar o Scaffold. Isso vai mudar quando começarmos a implementar nossos componentes.

Vamos começar com o primeiro dos três parâmetros: TimeText.

TimeText

O TimeText usa texto curvado internamente e oferece aos desenvolvedores uma maneira fácil de mostrar o horário, sem que seja necessário adicionar o elemento combinável nem ter trabalho com classes de horário.

As diretrizes do Material Design recomendam que você mostre o horário na parte de cima da tela no app. Confira um exemplo de como a tela vai ficar:

2a642b9ff3334e2a.png

Adicionar o TimeText é bem simples.

Encontre timeText = { }, e substitua pelo código a seguir:

Etapa 11

timeText = {
    TimeText(modifier = Modifier.scrollAway(listState))
},

Primeiro, criamos um elemento combinável TimeText. Poderíamos adicionar outros parâmetros para incluir texto antes e/ou depois do horário mostrado, mas estamos buscando uma abordagem mais simples aqui.

Ao criar TimeText com elementos de rolagem, como listas, a função TimeText precisa desaparecer da visualização conforme o usuário começa a rolar uma lista de itens para cima. Para isso, adicionamos um Modifier.scrollAway que vai rolar TimeText verticalmente dentro/fora da visualização, com base no estado de rolagem.

Tente executar o app. O horário vai ser mostrado e, se você rolar a tela, ele vai desaparecer.

43e90952cbcce9b0.png

A seguir, vamos falar sobre a Vignette.

Adicionar uma vinheta

Uma Vignette desfoca as bordas de cima e de baixo da tela do wearable ao mostrar uma página rolável.

Dependendo do caso de uso, os desenvolvedores podem especificar o desfoque da parte de cima, de baixo ou ambas.

Confira um exemplo:

7e85451de59e1d0.png

Como estamos trabalhando apenas com uma tela, que é rolável, é importante adicionar a vinheta para facilitar a leitura. Vamos fazer isso agora.

Encontre vignette = { }, e substitua pelo código a seguir:

Etapa 12

vignette = {
    // Only show a Vignette for scrollable screens. This code lab only has one screen,
    // which is scrollable, so we show it all the time.
    Vignette(vignettePosition = VignettePosition.TopAndBottom)
},

Leia o comentário para ver mais detalhes sobre quando usar e não usar uma vinheta. Em nosso caso, queremos que ela seja mostrada o tempo todo, e que as partes de cima e de baixo da tela fiquem desfocadas.

f4679e75e295642c.png

Você vai notar esse efeito ao observar as partes de cima e de baixo da tela, principalmente nos elementos roxos.

Agora, vamos concluir o parâmetro final do Scaffold: PositionIndicator.

Adicionar um PositionIndicator

O PositionIndicator, também conhecido como indicador de rolagem, fica do lado direito da tela para mostrar a posição atual do indicador com base no tipo de objeto de estado transmitido. Em nosso caso, o estado vai ser ScalingLazyListState.

Confira um exemplo:

ba42dce6b62e720f.png

Você pode se perguntar por que o indicador de posição precisa estar no nível do Scaffold, e não no da ScalingLazyColumn.

Devido à curvatura da tela, o indicador de posição precisa estar centralizado no smartwatch (Scaffold), não apenas na janela de visualização (ScalingLazyColumn). Caso contrário, ele pode ser cortado.

Por exemplo, no app abaixo, podemos presumir que o elemento combinável "Playlist" não faz parte da área de rolagem. O indicador de posição está centralizado na ScalingLazyColumn, mas não ocupa a tela inteira. Então, é possível notar que a maior parte é cortada.

8018e75f709e25a0.png

No entanto, se centralizarmos o indicador de posição em vez de usarmos toda a superfície visível, que é fornecida pelo Scaffold, o indicador vai ser mostrado com clareza.

1a82be61163ead86.png

Isso significa que o PositionIndicator exige que o ScalingLazyListState informando a posição na lista de rolagem esteja acima do Scaffold.

Observando atentamente, é possível notar que elevamos o ScalingLazyListState acima do Scaffold para ocultar ou mostrar o horário. Assim, no nosso caso, o trabalho já foi concluído.

Agora que explicamos por que o indicador de posição deveria estar no scaffold, vamos o adicionar ao app.

Encontre positionIndicator = { } e substitua pelo código abaixo:

Etapa 12

positionIndicator = {
    PositionIndicator(
        scalingLazyListState = listState
    )
}

Essa etapa é bastante simples: o PositionIndicator precisa do estado de rolagem para ser renderizado corretamente, e agora isso é possível.

Além disso, o indicador é ocultado quando o usuário não está rolando a tela, o que é um ótimo recurso.

Estamos usando o ScalingLazyListState, mas é possível implementar várias outras opções de rolagem com o PositionIndicator, como ScrollState e LazyListState. O indicador também pode processar o botão lateral

e a borda de rotação. Para conferir todas as opções, consulte o KDocs de cada versão.

Vamos conferir como ficou agora:

cfcbd3003744a6d.png

Tente rolar para cima e para baixo. O indicador de rolagem só será mostrado enquanto você estiver rolando a tela.

Muito bem! Você concluinterface uma demonstração da interface com a maioria dos elementos combináveis do Wear OS.

9. Parabéns

Parabéns! Você aprendeu as noções básicas do Compose no Wear OS.

Agora, você pode colocar em prática todo o conhecimento que você já tem sobre Compose e começar a criar apps incríveis para Wear OS.

Qual é a próxima etapa?

Confira os outros codelabs do Wear OS:

Leia mais

Feedback

Queremos saber sobre suas experiências com o Compose para Wear OS e o que você pode criar. Participe da discussão no canal #compose-wear do Kotlin Slack (link em inglês) e continue enviando feedback no Issue Tracker.

Divirta-se com os códigos!