Migrar do Material 2.5 para o Material 3 no Compose para Wear OS

O Material 3 Expressive (link em inglês) é a próxima evolução do Material Design. Ele inclui temas, componentes e recursos de personalização atualizados, como cores dinâmicas.

Este guia se concentra na migração da biblioteca Jetpack Wear Compose Material 2.5 (androidx.wear.compose) para a biblioteca Jetpack Wear Compose Material 3 (androidx.wear.compose.material3) para apps.

Abordagens

Para migrar o código do app do M2.5 para o M3, siga a mesma abordagem descrita no Guia de migração do Material do Compose para smartphone, em especial:

Dependências

O M3 tem um pacote e uma versão separados para o M2.5:

M2.5

implementation("androidx.wear.compose:compose-material:1.4.0")

M3

implementation("androidx.wear.compose:compose-material3:1.5.0-beta05")

Consulte as versões mais recentes do M3 na página de versões do Wear Compose Material 3.

A biblioteca Wear Compose Foundation versão 1.5.0-beta01 apresenta alguns novos componentes projetados para funcionar com componentes do Material 3. Da mesma forma, o SwipeDismissableNavHost da biblioteca Wear Compose Navigation tem uma animação atualizada ao ser executado no Wear OS 6 (nível 36 da API) ou em versões mais recentes. Ao atualizar para a versão do Wear Compose Material 3, sugerimos que você também atualize as bibliotecas Wear Compose Foundation e Navigation:

implementation("androidx.wear.compose:compose-foundation:1.5.0-beta05")
implementation("androidx.wear.compose:compose-navigation:1.5.0-beta05")

Temas

Nas versões M2.5 e M3, o tema combinável é chamado de MaterialTheme, mas os pacotes e parâmetros de importação são diferentes. No M3, o parâmetro Colors foi renomeado para ColorScheme, e o MotionScheme foi introduzido para implementar transições.

M2.5

import androidx.wear.compose.material.MaterialTheme

MaterialTheme(
        colors = AppColors,
        typography = AppTypography,
        shapes = AppShapes,
        content = content
)

M3

import androidx.wear.compose.material3.MaterialTheme

MaterialTheme(
        colorScheme = AppColorScheme,
        typography = AppTypography,
        shapes = AppShapes,
        motionScheme = AppMotionScheme,
        content = content
)

Cor

O sistema de cores no M3 é significativamente diferente do M2.5. O número de parâmetros de cor aumentou, eles têm nomes diferentes e são mapeados de forma diferente para os componentes do M3. No Compose, isso se aplica à classe Colors do M2.5, à classe ColorScheme do M3 e às funções relacionadas:

M2.5

import androidx.wear.compose.material.Colors

val appColorScheme: Colors = Colors(
   // M2.5 Color parameters
)

M3

import androidx.wear.compose.material3.ColorScheme

val appColorScheme: ColorScheme = ColorScheme(
   // M3 ColorScheme parameters
)

A tabela a seguir descreve as principais diferenças entre M2.5 e M3:

M2.5

M3

Color

foi renomeado como ColorScheme

13 Colors

28 Colors

N/A

novo tema de cores dinâmicas

N/A

novas cores terciárias para mais expressão

Temas de cores dinâmicas

Um novo recurso do M3 é a aplicação de temas de cores dinâmicas (link em inglês). Se os usuários mudarem as cores do mostrador do relógio, as cores na interface vão mudar para corresponder.

Use a função dynamicColorScheme para implementar o esquema de cores dinâmicas e forneça um defaultColorScheme como substituto caso o esquema de cores dinâmicas não esteja disponível.

@Composable
fun myApp() {
  val myColorScheme = myBrandColors()
  val dynamicColorScheme = dynamicColorScheme(LocalContext.current)
  MaterialTheme(colorScheme = dynamicColorScheme ?: myBrandColors) {...}
}

Tipografia

O sistema de tipografia (link em inglês) no M3 é diferente do M2 e inclui os seguintes recursos:

  • Nove novos estilos de texto
  • Fontes flexíveis, que permitem a personalização das escalas tipográficas para diferentes pesos, larguras e arredondamentos
  • AnimatedText, que usa fontes flexíveis

M2.5

import androidx.wear.compose.material.Typography

val Typography = Typography(
   // M2.5 TextStyle parameters
)

M3

import androidx.wear.compose.material3.Typography

val Typography = Typography(
   // M3 TextStyle parameters
)

Fontes flexíveis

Com as fontes flexíveis, os designers podem especificar a largura e o peso do tipo para tamanhos específicos.

Estilos de texto

Os seguintes TextStyles estão disponíveis no M3. Eles são usados por padrão por vários componentes do M3.

Tipografia

TextStyle

Tela

displayLarge, displayMedium, displaySmall

Título

titleLarge, titleMedium, titleSmall

Rótulo

labelLarge, labelMedium, labelSmall

Corpo

bodyLarge, bodyMedium, bodySmall, bodyExtraSmall

Numeral

numeralExtraLarge, numeralLarge, numeralMedium, numeralSmall, numeralExtraSmall

Arco

arcLarge, arcMedium, arcSmall

Forma

O sistema de formas (link em inglês) no M3 é diferente do M2. O número de parâmetros de forma aumentou, eles são nomeados de forma diferente e são mapeados de forma diferente para os componentes do M3. Os seguintes tamanhos de forma estão disponíveis:

  • Extrapequena
  • Pequeno
  • Média
  • Grande
  • Extragrande

No Compose, isso se aplica às classes Shapes do M2 e Shapes do M3:

M2.5

import androidx.wear.compose.material.Shapes

val Shapes = Shapes(
   // M2.5 Shapes parameters
)

M3

import androidx.wear.compose.material3.Shapes

val Shapes = Shapes(
   // M3 Shapes parameters
)

Use o mapeamento de parâmetros de formas do guia Migrar do Material 2 para o Material 3 no Compose como ponto de partida.

Transformação de formas

O M3 apresenta a transformação de formas: agora elas se transformam em resposta às interações.

O comportamento de transformação de formas está disponível como uma variação em vários botões circulares. Confira abaixo:

Botões

Função de transformação de forma

IconButton

IconButtonDefaults.animatedShape() anima o botão de ícone ao pressionar.

IconToggleButton

IconToggleButtonDefaults.animatedShape() anima o botão de alternância de ícone ao pressionar e

IconToggleButtonDefaults.variantAnimatedShapes() anima o botão de alternância de ícone ao pressionar e marcar/desmarcar.

TextButton

TextButtonDefaults.animatedShape() anima o botão de texto ao ser pressionado.

TextToggleButton

TextToggleButtonDefaults.animatedShapes() anima a alternância de texto ao pressionar, e TextToggleButtonDefaults.variantAnimatedShapes() anima a alternância de texto ao pressionar e marcar/desmarcar.

Componentes e layout

A maioria dos componentes e layouts do M2.5 está disponível no M3. No entanto, alguns componentes e layouts do M3 não existiam no M2.5. Além disso, alguns componentes do M3 têm mais variações do que os equivalentes no M2.5.

Embora alguns componentes exijam considerações especiais, os mapeamentos de funções abaixo são recomendados como ponto de partida:

Material 2.5

Material 3

androidx.wear.compose.material.dialog.Alert

androidx.wear.compose.material3.AlertDialog

androidx.wear.compose.material.Button

androidx.wear.compose.material3.IconButton ou androidx.wear.compose.material3.TextButton

androidx.wear.compose.material.Card

androidx.wear.compose.material3.Card

androidx.wear.compose.material.TitleCard

androidx.wear.compose.material3.TitleCard

androidx.wear.compose.material.AppCard

androidx.wear.compose.material3.AppCard

androidx.wear.compose.material.Checkbox

Sem equivalente do M3, migre para androidx.wear.compose.material3.CheckboxButton ou androidx.wear.compose.material3.SplitCheckboxButton

androidx.wear.compose.material.Chip

androidx.wear.compose.material3.Button ou
androidx.wear.compose.material3.OutlinedButton ou
androidx.wear.compose.material3.FilledTonalButton ou
androidx.wear.compose.material3.ChildButton

androidx.wear.compose.material.CompactChip

androidx.wear.compose.material3.CompactButton

androidx.wear.compose.material.InlineSlider

androidx.wear.compose.material3.Slider

androidx.wear.compose.material.LocalContentAlpha

Foi removido porque não é usado por Text ou Icon no Material 3

androidx.wear.compose.material.PositionIndicator

androidx.wear.compose.material3.ScrollIndicator

androidx.wear.compose.material.RadioButton

Sem equivalente do M3, migre para androidx.wear.compose.material3.RadioButton ou androidx.wear.compose.material3.SplitRadioButton

androidx.wear.compose.material.SwipeToRevealCard

androidx.wear.compose.material3.SwipeToReveal

androidx.wear.compose.material.SwipeToRevealChip

androidx.wear.compose.material3.SwipeToReveal

android.wear.compose.material.Scaffold

androidx.wear.compose material3.AppScaffold e androidx.wear.compose.material3.ScreenScaffold

androidx.wear.compose.material.SplitToggleChip

Não há equivalente no M3. Migre para androidx.wear.compose.material3.SplitCheckboxButton, androidx.wear.compose.material3.SplitSwitchButton ou androidx.wear.compose.material3.SplitRadioButton.

androidx.wear.compose.material.Switch

Não há equivalente no M3. Migre para androidx.wear.compose.material3.SwitchButton ou androidx.wear.compose.material3.SplitSwitchButton.

androidx.wear.compose.material.ToggleButton

androidx.wear.compose.material3.IconToggleButton ou androidx.wear.compose.material3.TextToggleButton

androidx.wear.compose.material.ToggleChip

androidx.wear.compose.material3.CheckboxButton ou
androidx.wear.compose.material3.RadioButton ou
androidx.wear.compose.material3.SwitchButton

androidx.wear.compose.material.Vignette

Removido por não estar incluído no design expressivo do Material 3 para Wear OS

Confira uma lista completa de todos os componentes do Material 3:

Material 3

Componente equivalente do Material 2.5 (se não for novo no M3)

androidx.wear.compose.material3.AlertDialog

androidx.wear.compose.material.dialog.Alert

androix.wear.compose.material3.AnimatedPage

Novo

androidx.wear.compose.material3.AnimatedText

Novo

androidx.wear.compose material3.AppScaffold

android.wear.compose.material.Scaffold (com androidx.wear.compose.material3.ScreenScaffold)

androidx.wear.compose.material3.Button

androidx.wear.compose.material.Chip

androidx.wear.compose.material3.ButtonGroup

Novo

androidx.wear.compose.material3.Card

androidx.wear.compose.material.Card

androidx.wear.compose.material3.CheckboxButton

androidx.wear.compose.material.ToggleChip com um controle de alternância de caixa de seleção

androidx.wear.compose.material3.ChildButton

androidx.wear.compose.material.Chip (somente quando não é necessário um plano de fundo)

androidx.wear.compose.material3.CircularProgressIndicator

androidx.wear.compose.material.CircularProgressIndicator

androidx.wear.compose.material3.CompactButton

androidx.wear.compose.material.CompactChip

androidx.wear.compose.material3.ConfirmationDialog

androidx.wear.compose.material.dialog.Confirmation

androidx.wear.compose.material3.curvedText

androidx.wear.compose.material.curvedText

androidx.wear.compose.material3.DatePicker

Novo

androidx.wear.compose.material3.Dialog

androidx.wear.compose.material.dialog.Dialog

androidx.wear.compose.material3.EdgeButton

Novo

androidx.wear.compose.material3.FadingExpandingLabel

Novo

androidx.wear.compose.material3.FilledTonalButton

androidx.wear.compose.material.Chip quando um plano de fundo tonal do botão é necessário

androidx.wear.compose.material3.HorizontalPageIndicator

androidx.wear.compose.material.HorizontalPageIndicator

androidx.wear.compose.material3.HorizontalPagerScaffold

Novo

androidx.wear.compose.material3.Icon

androidx.wear.compose.material.Icon

androidx.wear.compose.material3.IconButton

androidx.wear.compose.material.Button

androidx.wear.compose.material3.IconToggleButton

androidx.wear.compose.material.ToggleButton

androidx.wear.compose.material3.LevelIndicator

Novo

androidx.wear.compose.material3.LinearProgressIndicator

Novo

androidx.wear.compose.material3.ListHeader

androidx.wear.compose.material.ListHeader

androidx.wear.compose.material3.ListSubHeader

Novo

androidx.wear.compose.material3.MaterialTheme

androidx.wear.compose.material.MaterialTheme

androidx.wear.compose.material3.OpenOnPhoneDialog

Novo

androidx.wear.compose.material3.Picker

androidx.wear.compose.material.Picker

androidx.wear.compose.material3.PickerGroup

androidx.wear.compose.material.PickerGroup

androix.wear.compose.material3.RadioButton

androidx.wear.compose.material.ToggleChip com um controle de alternância de botão de opção

androidx.wear.compose.material3.ScreenScaffold

android.wear.compose.material.Scaffold (com androidx.wear.compose material3.AppScaffold)

androidx.wear.compose.material3.ScrollIndicator

androidx.wear.compose.material.PositionIndicator

androidx.wear.compose.material3.scrollaway

androidx.wear.compose.material.scrollaway

androidx.wear.compose.material3.SegmentedCircularProgressIndicator

Novo

androidx.wear.compose.material3.Slider

androidx.wear.compose.material.InlineSlider

androidx.wear.compose.material3.SplitRadioButton

androidx.wear.compose.material.SplitToggleChip

androidx.wear.compose.material3.SplitCheckboxButton

androidx.wear.compose.material.SplitToggleChip

androidx.wear.compose.material3.SplitSwitchButton

androidx.wear.compose.material.SplitToggleChip

androidx.wear.compose.material3.Stepper

androidx.wear.compose.material.Stepper

androidx.wear.compose.material3.SwipeToDismissBox

androidx.wear.compose.material.SwipeToDismissBox

androidx.wear.compose.material3.SwipeToReveal

androidx.wear.compose.material.SwipeToRevealCard e androidx.wear.compose.material.SwipeToRevealChip

androidx.wear.compose.material3.SwitchButton

androidx.wear.compose.material.ToggleChip com um controle de ativação/desativação

androidx.wear.compose.material3.Text

androidx.wear.compose.material.Text

androidx.wear.compose.material3.TextButton

androidx.wear.compose.material.Button

androidx.wear.compose.material3.TextToggleButton

androidx.wear.compose.material.ToggleButton

androidx.wear.compose.material3.TimeText

androidx.wear.compose.material.TimeText

androidx.wear.compose.material3.VerticalPagerScaffold

Novo

Por fim, uma lista de alguns componentes relevantes da biblioteca Wear Compose Foundation versão 1.5.0-beta01:

Wear Compose Foundation 1.5.0-beta

androidx.wear.compose.foundation.hierarchicalFocusGroup

Usada para anotar elementos combináveis em um aplicativo, acompanhar a parte ativa da composição e coordenar o foco.

androidx.compose.foundation.pager.HorizontalPager

Um pager de rolagem horizontal, criado com base nos componentes do Compose Foundation e com melhorias específicas do Wear para aumentar o desempenho e a conformidade com as diretrizes do Wear OS.

androidx.compose.foundation.pager.VerticalPager

Um pager de rolagem vertical, criado com base nos componentes do Compose Foundation e com melhorias específicas do Wear para melhorar o desempenho e a conformidade com as diretrizes do Wear OS.

androidx.wear.foundation.lazy.TransformingLazyColumn

Pode ser usado em vez de ScalingLazyColumn para adicionar efeitos de transformação de rolagem a cada item.

Botões

Os botões no M3 são diferentes do M2.5. O ícone M2.5 foi substituído por Button. A implementação Button oferece valores padrão para Text, maxLines e textAlign. Esses valores padrão podem ser substituídos no elemento Text.

M2.5

import androidx.wear.compose.material.Chip

//M2.5 Buttons
Chip(...)
CompactChip(...)
Button(...)

M3

import androidx.wear.compose.material3.Button

//M3 Buttons
Button(...)
CompactButton(...)
IconButton(...)
TextButton(...)

O M3 também inclui novas variações de botões mostradas na Visão geral de referência da API do Compose Material 3.

O M3 apresenta um novo botão: EdgeButton. O EdgeButton está disponível em quatro tamanhos diferentes: extrapequeno, pequeno, médio e grande. A implementação EdgeButton fornece um valor padrão para maxLines dependendo do tamanho, que pode ser personalizado.

Se você estiver usando TransformingLazyColumn e ScalingLazyColumn, transmita o EdgeButton para o ScreenScaffold para que ele se transforme, mudando a forma com a rolagem. Confira o código abaixo para saber como usar EdgeButton com ScreenScaffold e TransformingLazyColumn.

import androidx.wear.compose.material3.EdgeButton
import androidx.wear.compose.material3.ScreenScaffold

ScreenScaffold(
   scrollState = state,
   contentPadding = contentPadding,
   edgeButton = {
      EdgeButton(...)
   }
){ contentPadding ->
   TransformingLazyColumn(state = state, contentPadding = contentPadding,){
   // additional code here
   }
}

Scaffold

O Scaffold no M3 é diferente do M2.5. No M3, AppScaffold e o novo elemento combinável ScreenScaffold substituíram o Scaffold. 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. ​​Ele fornece um slot para o conteúdo principal do aplicativo, que geralmente é fornecido por um componente de navegação como SwipeDismissableNavHost.

Você declara um AppScaffold para a atividade e usa um ScreenScaffold para cada tela.

M2.5

import androidx.wear.compose.material.Scaffold

Scaffold {...}

M3

import androidx.wear.compose.material3.AppScaffold
import androidx.wear.compose.material3.ScreenScaffold

AppScaffold {
   // Define the navigation hierarchy within the AppScaffold,
   // such as using SwipeDismissableNavHost.
   SwipeDismissableNavHost(...) {
      composable("home") {
         HomeScreen()
      }
      //other screens
   }
}
fun HomeScreen() {
    val scrollState = rememberScrollState()
    ScreenScaffold(scrollState = scrollState) {
    //rest of the screen code
    }
}

Se você estiver usando um HorizontalPager com HorizontalPagerIndicator, poderá migrar para HorizontalPagerScaffold. O HorizontalPagerScaffold é colocado em um AppScaffold. AppScaffold e HorizontalPagerScaffold definem a estrutura de um Pager e coordenam as transições dos componentes HorizontalPageIndicator e TimeText.

O HorizontalPagerScaffold mostra o HorizontalPageIndicator no centro da tela por padrão e coordena a exibição/ocultação de TimeText e HorizontalPageIndicator de acordo com o Pager que está sendo paginado. Isso é determinado pelo PagerState.

Há também um novo componente AnimatedPage, que anima uma página em um Pager com um efeito de escalonamento e máscara com base na posição dela.

import androidx.wear.compose.material3.AppScaffold
import androidx.wear.compose.material3.HorizontalPagerScaffold
import androidx.wear.compose.material3.ScreenScaffold
import androidx.wear.compose.foundation.pager.HorizontalPager
import androidx.wear.compose.foundation.pager.rememberPagerState

AppScaffold {
    val pagerState = rememberPagerState(pageCount = { 10 })

    HorizontalPagerScaffold(pagerState = pagerState) {
       HorizontalPager(
          state = pagerState,
        ) { page ->
            AnimatedPage(pageIndex = page, pagerState = pagerState) {
                ScreenScaffold {

   }
}

Por fim, o M3 apresenta um VerticalPagerScaffold que segue o mesmo padrão do HorizontalPagerScaffold:

import androidx.wear.compose.material3.AppScaffold
import androidx.wear.compose.material3.HorizontalPagerScaffold
import androidx.wear.compose.material3.ScreenScaffold
import androidx.wear.compose.foundation.pager.VerticalPager
import androidx.wear.compose.foundation.pager.rememberPagerState

AppScaffold {
   val pagerState = rememberPagerState(pageCount = { 10 })

   VerticalPagerScaffold(pagerState = pagerState) {
      VerticalPager(
         state = pagerState
      ) { page ->
             AnimatedPage(pageIndex = page, pagerState = pagerState){
                ScreenScaffold {
        
   }
}

Marcador de posição

Há algumas mudanças na API entre o M2.5 e o M3. O Placeholder.PlaceholderDefaults agora oferece dois modificadores:

  • Modifier.placeholder, que é desenhado em vez de conteúdo que ainda não foi carregado.
  • Um efeito de brilho de marcador de posição Modifier.placeholderShimmer que fornece um efeito de brilho de marcador de posição executado em um loop de animação enquanto aguarda o carregamento dos dados.

Confira abaixo outras mudanças no componente Placeholder.

M2.5

M3

PlaceholderState.startPlaceholderAnimation

Foi removida

PlaceholderState.placeholderProgression

Foi removida

PlaceholderState.isShowContent

Foi renomeado como !PlaceholderState.isVisible

PlaceholderState.isWipeOff

Foi removida

PlaceholderDefaults.painterWithPlaceholderOverlayBackgroundBrush

foi removido

PlaceholderDefaults.placeholderBackgroundBrush

Foi removida

PlaceholderDefaults.placeholderChipColors

Foi removida

SwipeDismissableNavHost

SwipeDismissableNavHost faz parte de wear.compose.navigation. Quando esse componente é usado com o M3, o MaterialTheme do M3 atualiza o LocalSwipeToDismissBackgroundScrimColor e o LocalSwipeToDismissContentScrimColor.

TransformingLazyColumn

O TransformingLazyColumn faz parte do wear.compose.lazy.foundation e adiciona suporte para animações de escalonamento e transformação em itens de lista durante a rolagem, melhorando a experiência do usuário.

Assim como ScalingLazyColumn, ele fornece rememberTransformingLazyColumnState() para criar um TransformingLazyColumnState que é lembrado em todas as composições.

Para adicionar animações de escalonamento e transformação, adicione o seguinte a cada item da lista:

  • Modifier.transformedHeight, que permite calcular a altura transformada dos itens usando um TransformationSpec. Use rememberTransformationSpec(), a menos que precise de mais personalização.
  • Um SurfaceTransformation
import androidx.wear.compose.material3.AppScaffold
import androidx.wear.compose.material3.ScreenScaffold
import androidx.wear.compose.material3.SurfaceTransformation
import androidx.wear.compose.material3.lazy.rememberTransformationSpec
import androidx.wear.compose.material3.lazy.transformedHeight
import androidx.wear.compose.foundation.lazy.rememberTransformingLazyColumnState
import androidx.wear.compose.foundation.lazy.TransformingLazyColumn

val state = rememberTransformingLazyColumnState()
val transformationSpec = rememberTransformationSpec()
AppScaffold {
   ScreenScaffold(state) { contentPadding ->
      TransformingLazyColumn(state = state, contentPadding = contentPadding) {
         items(count = 50) {
            Button(
               onClick = {},
               modifier =
                        Modifier.fillMaxWidth().transformedHeight(this, transformationSpec),
                        transformation = SurfaceTransformation(transformationSpec),
                    ) {
                        Text("Item $it")
                    }
                }
            }
        }
    }

Links úteis

Para saber mais sobre a migração do M2.5 para o M3 no Compose, consulte os recursos abaixo.

Amostras

Referência da API e código-fonte

Design