Codelab sobre o Compose para Wear OS

1. Introdução

2c9dd335c9d65f10.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 o Material Design integrado, 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 (TransformingLazyColumn)
  • 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 AppScaffold e o ScreenScaffold, também terá um texto curvo mostrando o horário na parte de cima da tela e um indicador de rolagem na lateral do dispositivo.

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

3162140d003d8e31.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 codelab-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 a qualquer momento mudando a configuração de execução na barra de ferramentas.

51cb2645eece1f20.png

Abrir o projeto no Android Studio

  1. Na janela "Welcome to Android Studio", selecione c01826594f360d94.png Open….
  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.

271451f93a57db41.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 TransformingLazyColumn.
  • 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 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-material3

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. Como alternativa à versão compose-material3, você pode usar androidx.wear.compose:compose-material, mas não misture o Material 3 e o 2.5 no mesmo app. Recomendamos o uso do material3, já que ele é compatível com o design expressivo do Material 3.

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:

dependencies {
    val composeBom = platform(libs.androidx.compose.bom)

    // General compose dependencies
    implementation(composeBom)
    implementation(libs.androidx.activity.compose)
    implementation(libs.compose.ui.tooling.preview)

    implementation(libs.androidx.material.icons.extended)

    // Compose for Wear OS Dependencies
    implementation(libs.wear.compose.material)

    // Foundation is additive, so you can use the mobile version in your Wear OS app.
    implementation(libs.wear.compose.foundation)

    // Compose preview annotations for Wear OS.
    implementation(libs.androidx.compose.ui.tooling)

    implementation(libs.horologist.compose.layout)

    coreLibraryDesugaring(libs.desugar.jdk.libs)

    debugImplementation(libs.compose.ui.tooling)
    debugImplementation(libs.androidx.ui.test.manifest)
    debugImplementation(composeBom)
}

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-material3) é incluída. Isso significa que você não verá nem incluirá androidx.compose.material:material3 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 {
     /* *************************** Part 4: Wear OS Scaffold *************************** */
    // TODO (Start): Create a AppScaffold (Wear Version)

    // TODO: Swap to TransformingLazyColumnState
    val listState = rememberLazyListState()

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

    /* *************************** Part 3: ScalingLazyColumn *************************** */
    // TODO: Swap a TransformingLazyColumn (Wear's version of LazyColumn)
    LazyColumn(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        state = listState,
    ) {
        // TODO: Remove item; for beginning only.
        item { StartOnlyTextComposables() }

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

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

    // TODO (End): Create a ScreenScaffold (Wear Version)
    // TODO (End): Create a AppScaffold (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. Por isso, ao analisar o arquivo theme/Theme.kt, você vai notar que não modificamos as formas.

Se quiser, você pode abrir o theme/Theme.kt para conferir mais detalhes, mas o processo é igual ao usado para smartphones.

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() }
item { TextExample() }
item { CardExample() }

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

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 combináveis simples

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 elemento combinável de botão para ícone

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

Etapa 2

// TODO: Create a Icon Button Composable
@Composable
fun IconButtonExample(
    modifier: Modifier = Modifier,
) {
    FilledIconButton(
        onClick = { /* ... */ },
        modifier = modifier,
    ) {
        Icon(
            imageVector = Icons.Rounded.Phone,
            contentDescription = "triggers phone action",
        )
    }
}

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

Vamos analisar o código:

Usamos um FilledIconButton, que é um botão circular com um ícone, um plano de fundo colorido e uma cor de conteúdo contrastante. Ele oferece um único slot para usar um ícone ou imagem.

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, não é necessário centralizar o botão nessa etapa, porque ele será corrigido automaticamente mais tarde ao migrar de LazyColumn para TransformingLazyColumn..

Se você executar o app, o resultado ficará como mostrado abaixo. Não se preocupe se o botão não estiver centralizado:

9346dbd2b8bc6a56.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) {
   ListHeader{
      Text(
           modifier = modifier
               .fillMaxWidth(),
           textAlign = TextAlign.Center,
           text = stringResource(R.string.hello_compose_codelab),
       )
   }
}

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. Como uma lista será adicionada mais tarde, vamos colocar esse texto em um ListHeader para que o conteúdo seja preenchido no início e no fim.

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:

dcad71112a91d706.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.

Estamos indo 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.AutoMirrored.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.

Veja abaixo como ficou. Não se preocupe em adicionar mais padding inferior, porque isso será corrigido ao migrar de LazyColumn para TransformingLazyColumn:

faf2fe359baf0946.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

O objetivo dos ícones é 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.

É possível implementar um ícone usando um Button. Para você ter uma ideia do que pode ser criado, veja algumas variações da função combinável Button:

13c7dc5e08b5d2d4.png 9859b3f9880f75af.png

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,
) {
    Button(
        modifier = modifier,
        onClick = { /* ... */ },
        icon = {
            Icon(
                imageVector = Icons.Rounded.SelfImprovement,
                contentDescription = "triggers meditation action",
            )
        },
    ) {
        Text(
            text = "5 minute Meditation",
            maxLines = 1,
            overflow = TextOverflow.Ellipsis,
        )
    }
}

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

Ele também tem um ícone e um slot para o conteúdo do corpo combinável mostrado no botão, para o qual criamos 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 ver o resultado. Não se esqueça de rolar a tela para baixo. Você não precisa adicionar mais padding na parte de baixo, porque isso será corrigido ao migrar de LazyColumn para TransformingLazyColumn:

22afab093efc7fc5.png

Agora, vamos abordar a variação do Button, o elemento combinável SwitchButton.

Criar um elemento combinável SwitchChip

O SwitchButton é semelhante a um Button, mas permite que o usuário interaja com um botão de alternância.

eb38c8acb3ac996.png

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

Etapa 6

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

Agora, a função combinável SwitchChipExample(), em que esse código se encontra, gera um SwitchChip 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 SwitchChip funciona com a alternância, mesmo sem causar nenhuma mudança de estado.

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

Vamos criar um 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:

8ef93a35bdb7302a.png

Agora você já viu 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 TransformingScalingLazyColumn

É 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.

TransformingLazyColumn estende a LazyColumn para que esse elemento permita 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:

c056381ba4a7475d.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:

6dbb1e13f99e5e1f.gif

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

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

Converter para um TransformingLazyColumnState

Em MainActivity.kt, pesquise "TODO: Swap to TransformingLazyColumnState" e substitua o comentário e a linha abaixo por esse código. Observe como especificamos quais são o primeiro e o último componentes para que os melhores valores de padding sejam usados para evitar qualquer recorte de conteúdo.

Etapa 7

// TODO: Swap to TransformingLazyColumnState
val listState = rememberTransformingLazyColumnState()
val transformationSpec = rememberTransformationSpec()

Os nomes são quase idênticos. Assim como o LazyListState processa o estado de uma LazyColumn, o TransformingLazyColumnState processa o estado de uma TransformingLazyColumn.

Também especificamos uma transformationSpec aqui para adicionar transformações para os itens conforme eles rolam pela tela.

Converter para uma TransformingLazyColumn

Agora, vamos trocar para o elemento TransformingLazyColumn.

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

Em seguida, remova contentPadding, verticalArrangement e modifier. O TransformingLazyColumn 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. Na maioria dos 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 no ListHeader (link em inglês) como o primeiro item.

Etapa 8

// TODO: Swap a TransformingLazyColumn (Wear's version of LazyColumn)
TransformingLazyColumn(
    state = listState,
    contentPadding = contentPadding)

Adicionar um efeito de transformação de rolagem aos itens

Agora, vamos adicionar um efeito ShapeMorphing aos elementos TransformingLazyColumn usando o Modifier e SurfaceTransformation a seguir. Aplique o mesmo código a todos os componentes

(exceto IconButtonExample, que ainda não é compatível com esse recurso)..

Etapa 9

TextExample(
   modifier = Modifier.fillMaxWidth().transformedHeight(this, transformationSpec),
   transformation = SurfaceTransformation(transformationSpec),
)

Pronto! Este é o resultado:

4c97e27b6acb83ef.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 AppScaffold e ScreenScaffold oferecem 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, eles permitem usar três layouts específicos do Wear com componentes de nível superior: horário, indicador de rolagem/posição e indicador de página.

Os elementos ficam assim:

TimeText

ScrollIndicator

HorizontalPageIndicator

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

Os componentes de scaffolding AppScaffold e ScreenScaffold definem o layout da estrutura de uma tela e coordenam as transições dos componentes ScrollIndicator e TimeText.

O AppScaffold permite que elementos estáticos da tela, como TimeText, fiquem visíveis durante transições no app, como o gesto de deslizar para fechar. O ScreenScaffold mostra o ScrollIndicator no centro da tela por padrão e coordena a exibição/ocultação de TimeText e ScrollIndicator.

Adicionar um Scaffold

Vamos adicionar o código boilerplate do AppScaffold e do ScreenScaffold agora.

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

Etapa 9

WearAppTheme {
// TODO (Start): Create a AppScaffold (Wear Version)
AppScaffold {

Encontre "TODO (Start): Create a ScreenScaffold (Wear Version)" e adicione o código abaixo dele.

// TODO (Start): Create a ScreenScaffold (Wear Version)
ScreenScaffold( 
    scrollState = listState,
    contentPadding = rememberResponsiveColumnPadding(
       first = ColumnItemType.IconButton,
       last = ColumnItemType.Button,
    ),
){contentPadding ->

Agora, adicione a chave de fechamento no local certo.

Encontre "TODO (End): Create a ScreenScaffold (Wear Version)" e adicione a chave de fechamento:

Etapa 10

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

Encontre "TODO (End): Create a AppScaffold (Wear Version)" e adicione a chave de fechamento:

Etapa 10

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

Primeiro, vamos executar o app. Você verá algo como:

97e417901b8f8229.png

Observe que ele adiciona:

  • Um TimeText que 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. Além disso, as diretrizes do Material Design recomendam que você mostre o horário na parte de cima da tela no app, e ele desaparece durante a rolagem.
  • Um ScrollIndicator, que é um indicador do lado direito da tela e mostra a localização atual do indicador com base no tipo de objeto de estado transmitido. Em nosso caso, o estado vai ser TransformingLazyColumnState (link em inglês).

Vamos ver como ficou agora:

fd00c8fc4f7283ef.png

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

Adicionar um botão de ajuste à borda

O EdgeButton é um novo botão expressivo do Material do Compose M3 para a versão do Wear OS. O contêiner que se ajusta às bordas é uma nova forma que envolve o formato circular e maximiza o espaço dentro dele.

O ScreenScaffold fornece um slot para um EdgeButton que ocupa o espaço disponível abaixo de uma lista de rolagem. Ele vai aumentar e aparecer quando o usuário rolar até o fim da lista, mas diminuir e desaparecer quando ele rolar para cima. Vamos adicionar um EdgeButton ao nosso código:

Etapa 11

ScreenScaffold(
  scrollState = listState,
  contentPadding = rememberResponsiveColumnPadding(
    first = ColumnItemType.IconButton,
    last = ColumnItemType.Button,
  ),
/* *************************** Part 11: EdgeButton *************************** */
  // TODO: Add a EdgeButton
   edgeButton = {
     EdgeButton(
      onClick = { /* ... */ },
      buttonSize = EdgeButtonSize.Medium) {
        Text(stringResource(R.string.more))
      }
   }

É possível especificar 4 tamanhos diferentes para um EdgeButton: ExtraSmall, Small, Medium e Large.

Vamos ver como ficou agora:

3a973bbfe4941e67.png

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:

Leitura adicional

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.

Boa codificação!