Codelab sobre o Compose para Wear OS

1. Introdução

4d28d16f3f514083.png

Com o Compose para Wear OS, você pode usar o que aprendeu sobre a criação de apps para dispositivos móveis 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 IU, assim como em dispositivos móveis, 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ê criará vários elementos específicos do Wear que podem ser compostos (simples e complexos) e, no final, poderá começar a programar os próprios apps para Wear OS. Vamos começar!

O que você aprenderá

  • Semelhanças e diferenças entre o Compose para dispositivos móveis e para Wear OS.
  • Elementos do Wear OS que podem ser compostos e são parecidos com os elementos comuns em dispositivos móveis.
  • Novos elementos do Wear OS que podem ser compostos.
  • O elemento LazyColumn do Wear OS (ScalingLazyColumn)).
  • A versão do elemento Scaffold do Wear OS.

O que você criará

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

Como você 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.

Veja como o app ficará quando você terminar o codelab:

b7bd20036af4859d.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/googlecodelabs/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:

Fazer o download do ZIP

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

8a2e49d6d6d2609d.png

Abrir o projeto no Android Studio

  1. Na janela "Welcome to Android Studio", selecione 1f5145c42df4129a.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ê fará todo o trabalho.

7668d2915856b849.png

Conhecer o código inicial

  • O build.gradle contém uma configuração básica de app. Ele inclui as dependências necessárias para criar um app para Wear OS que pode ser composto. Abordaremos as semelhanças e diferenças entre o Jetpack Compose para dispositivos móveis e 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 de nível superior do app que podem ser compostos, 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.

d92519e0b932f964.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 IU, ambiente de execução, compilador e animação permanecerão as mesmas.

No entanto, você precisará usar as bibliotecas Material, Foundation e Navigation do Wear OS, que são diferentes das usadas anteriormente no app para dispositivos móveis.

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

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

Comparação

Dependência de dispositivos móveis(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

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 mobile version in your Wear OS app.
implementation "androidx.wear.compose:compose-foundation:$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). Esse é um recurso complementar e pode ser usado com a foundation padrão para dispositivos móveis. É 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 a 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 IU.

Role a tela para baixo até a função WearApp() que pode ser composta. 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 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: Similar composables to Mobile ******************* */
            item { ButtonExample(contentModifier, iconModifier) }
            item { TextExample(contentModifier) }
            item { CardExample(contentModifier, iconModifier) }

            /* ********************* Part 2: Wear OS Only 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 em apps para dispositivos móveis, 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ê verá que não modificamos as formas.

Se quiser, você pode abrir o theme/Theme.kt para analisar melhor, mas os elementos são iguais aos usados para dispositivos móveis.

A seguir, criaremos alguns modificadores para os elementos do Wear que serão desenvolvidos para que eles não precisem ser especificados todas as vezes. Basicamente, centralizamos o conteúdo e adicionamos padding.

Em seguida, criamos um elemento LazyColumn, usado para produzir uma lista de rolagem vertical que inclui vários itens, da mesma forma que ocorre em apps para dispositivos móveis.

Código:

item { StartOnlyTextComposables() }

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

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

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

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

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

5. Adicionar elementos simples que podem ser compostos

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 que pode ser composto.

Criar um botão que pode ser composto

Abra o ReusableComponents.kt no módulo start, pesquise "TODO: Create a Button Composable" e substitua o método que pode ser composto 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 ButtonExample() que pode ser composta, 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 para um botão em apps para dispositivos móveis, mas neste caso, usamos ButtonDefault.LargeButtonSize. É importante que você use esses tamanhos de apresentação, porque eles são otimizados para dispositivos Wear OS.

Depois, definimos o evento de clique como uma lamba vazia. Em nosso caso, os elementos que podem ser compostos servem apenas para uma demonstração, entã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 para Icon anteriormente. 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 terá esta aparência:

f9fce435c935d610.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 de texto que pode ser composto

No ReusableComponents.kt, pesquise "TODO: Create a Text Composable" e substitua o método que pode ser composto atual pelo código a seguir.

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 Text que pode ser composto, definir o modificador, alinhar o texto, definir uma cor e, por fim, configurar o texto em si usando um recurso de string.

Para desenvolvedores do Compose, os elementos de texto que podem ser compostos são bastante conhecidos, e o código é idêntico ao usado em apps para dispositivos móveis.

Este é o resultado:

52a4e318d12d7ba5.png

A função TextExample() que pode ser composta, em que colocamos nosso código, agora gera um elemento de texto que pode ser composto na nossa cor principal do Material.

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 fornece recursos de string para dispositivos redondos e não redondos. Portanto, se executarmos esse código em um emulador quadrado, a string mudará:

27e50afef57b7717.png

Até aqui, tudo bem. Vamos analisar o último elemento que pode ser composto, o Card.

Criar um card que pode ser composto

No ReusableComponents.kt, pesquise "TODO: Create a Card" e substitua o método que pode ser composto atual pelo código a seguir.

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 = { /* ... */ }
    ) {
        Column(modifier = Modifier.fillMaxWidth()) {
            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 usaremos AppCard. O TitleCard é focado apenas em texto.

Vamos criar o elemento AppCard que pode ser composto, definir o modificador dele, adicionar um Icon, adicionar vários parâmetros de Text que podem ser compostos (um para cada espaço diferente no card) e, por fim, definir o texto principal.

Este é o resultado:

dcb5e5bebf9f19d9.png

Você provavelmente já percebeu que, para esses elementos que podem ser compostos, o código do Compose é praticamente igual ao usado para dispositivos móveis, o que é ótimo. Isso significa que você pode colocar em prática todo o conhecimento que já adquiriu.

Agora, vamos analisar alguns novos elementos que podem ser compostos.

6. Adicionar elementos que podem ser compostos exclusivos para Wear OS

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

Criar um ícone que pode ser composto

Os ícones são especificados nas diretrizes do Material Design (link em inglês), mas não há uma função que pode ser composta na biblioteca do Material para dispositivos móveis.

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 que você tenha uma ideia do que pode ser criado, veja algumas variações da função Chip que pode ser composta:

Vamos programar o código.

No ReusableComponents.kt, pesquise "TODO: Create a Chip" e substitua o método que pode ser composto atual pelo código a seguir.

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 Chip que pode ser composto usa muitos dos mesmos parâmetros utilizados em outros elementos (modificador e onClick), não precisamos repassar esses pontos.

Ele também usa um ícone e um marcador, para o qual criamos um Text que pode ser composto.

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

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

77bde81f8f290f87.png

Agora, vamos abordar a variação do Toggle, o elemento que pode ser composto ToggleChip.

Criar um ToggleChip que pode ser composto

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 que pode ser composto atual pelo código a seguir.

Etapa 6

// TODO: Create a ToggleChip Composable
@Composable
fun ToggleChipExample(modifier: Modifier = Modifier) {
    var checked by remember { mutableStateOf(true) }
    ToggleChip(
        modifier = modifier,
        checked = checked,
        toggleIcon = {
            ToggleChipDefaults.SwitchIcon(checked = checked)
        },
        onCheckedChange = {
            checked = it
        },
        label = {
            Text(
                text = "Sound",
                maxLines = 1,
                overflow = TextOverflow.Ellipsis
            )
        }
    )
}

Agora, a função ToggleChipExample() que pode ser composta, 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 IU para apresentar as possibilidades do Wear OS.

Em um app normal, é recomendável transmitir o estado marcado e o 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 ícone de alternância para mostrar a chave que queremos. Aqui, usaremos as configurações padrão.

Vamos criar um lambda para mudar o estado e, por fim, definir o marcador com um Text que pode ser composto e configurar alguns parâmetros básicos.

Este é o resultado:

b76b501e91a64969.png

Agora você já viu vários elementos que podem ser compostos específicos do Wear OS. Como mencionado, a maior parte do código é quase igual ao usado em apps para dispositivos móveis.

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:

28460354eaf16eea.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.

Veja um exemplo mais concreto de um app:

307c969dccf58e49.gif

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

Agora que você viu o ScalingLazyListState em ação, vamos começar a converter nosso 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 um LazyColumn, o ScalingLazyListState processa o estado de um ScalingLazyColumn.

Converter para um ScalingLazyColumn

Agora, trocaremos para o ScalingLazyColumn.

No MainActivity.kt, pesquise "TODO: Swap a ScalingLazyColumn" e substitua essa linha e a que está abaixo dela pelo código a seguir.

Etapa 8

        // TODO: Swap a ScalingLazyColumn (Wear's version of LazyColumn)
        ScalingLazyColumn(

Pronto! Este é o resultado:

264ab059418a6526.png

Você verá 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, em vez de barra de apps, FAB, gaveta ou outros elementos específicos para dispositivos móveis, ele tem suporte para três layouts específicos do Wear com componentes de nível superior: horário, vinheta e indicador de rolagem/posição.

Além disso, ele funciona em dispositivos redondos e não redondos.

Os elementos ficam assim:

TimeText

Vignette

PositionIndicator

Analisaremos cada componente em detalhes, mas primeiro 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 IU.

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ê verá algo como:

2ddc667e07d8f04c.png

Note que o comportamento continua praticamente igual mesmo depois de adicionar o Scaffold. Isso 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 que pode ser composto nem ter trabalho com classes de horário.

As diretrizes do Material Design exigem que você exiba o horário na parte de cima da tela em qualquer sobreposição ou app. Veja um exemplo de como a tela ficará:

29671ae0a7c3225b.png

Adicionar o TimeText é bem simples.

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

Etapa 11

timeText = {
    if (!listState.isScrollInProgress) {
        TimeText()
    }
},

Vamos adicionar um pouco mais de lógica para ocultar o horário caso o usuário comece a rolar a tela.

Depois disso, basta criar um TimeText que pode ser composto. 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.

Tente executar o app. Você verá o horário, mas ele desaparecerá ao rolar a tela.

896aaebb9a89bbe8.png

A seguir, falaremos 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.

Veja um exemplo:

689ac8becaac6824.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 a vinheta seja mostrada o tempo todo e que as partes de cima e de baixo da tela fiquem desfocadas.

9a91313e5d59f49e.png

Você verá 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 será ScalingLazyListState.

Veja um exemplo:

181b19b55ce37251.png

Vamos começar.

Observando atentamente, é possível notar que nós elevamos o ScalingLazyListState acima do Scaffold.

Você pode estar se perguntando por que fizemos isso quando esse elemento poderia ficar acima do ScalingLazyColumn.

Isso se deve à curvatura da tela, que faz com que o indicador de posição precise estar centralizado no relógio, e não apenas na janela de visualização. Caso contrário, ele poderia ficar cortado.

Por exemplo, no app abaixo, podemos presumir que o elemento "Playlist" não faz parte da área de rolagem:

c9f96a90a3e811fb.png

Se o indicador de posição não estivesse centralizado na tela (como no exemplo), e sim na janela de visualização da lista, ele seria cortado devido à tela redonda.

Agora que explicamos por que ele foi tão elevado, vamos adicionar esse indicador ao app.

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

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 ver todas as opções, consulte o KDocs de cada versão.

Vamos ver como ficou agora:

8c278b78ab008cbb.png

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

Muito bem! Você concluiu uma demonstração da IU com a maioria dos elementos do Wear OS que podem ser compostos.

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 dispositivos móveis 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