Migrar do Material 2 para o Material 3 no Compose

O Material Design 3 (link em inglês) é a próxima evolução do Material Design. Ele inclui temas, componentes e recursos de personalização do Material You atualizados, como cores dinâmicas. É uma atualização do Material Design 2 e é coeso com o novo estilo visual e a interface do sistema no Android 12 e versões mais recentes.

Este guia se concentra na migração da biblioteca Jetpack do Compose Material (androidx.compose.material) para a biblioteca Jetpack do Compose Material 3 (androidx.compose.material3).

Abordagens

Em geral, não use M2 e M3 em um único app de longo prazo. Isso ocorre porque os dois sistemas de design e as respectivas bibliotecas diferem significativamente em termos de designs de UX/IU e implementações do Compose.

O app pode usar um sistema de design, como o criado pelo Figma. Nesses casos, também recomendamos que você ou sua equipe de design migre de M2 para M3 antes de iniciar a migração do Compose. Não faz sentido migrar um app para o M3 se o design da UX/UI se baseia no M2.

Além disso, a abordagem da migração varia de acordo com o tamanho, a complexidade e o design da UX/UI do app. Isso minimiza o impacto na sua base de código. Adote uma abordagem por etapas.

Quando migrar

Inicie a migração assim que possível. No entanto, é importante considerar se o app está em uma posição realista para migrar totalmente do M2 para o M3. Considere alguns cenários de bloqueio antes de começar:

Cenário Abordagem recomendada
Sem bloqueadores Iniciar a migração por etapas.
Um componente do M2 ainda não está disponível no M3. Consulte a seção Componentes e layouts abaixo. Iniciar a migração por etapas.
Você ou sua equipe de design não migraram o sistema de design do app do M2 para o M3. Migrar o sistema de design do M2 para o M3 e depois iniciar a migração por etapas.

Mesmo que você seja afetado pelos cenários acima, é necessário adotar uma abordagem por etapas para a migração antes de confirmar e lançar uma atualização do app. Nesses casos, use o M2 e o M3 em conjunto e, gradualmente, desative o M2 enquanto migra para o M3.

Abordagem por etapas

As etapas gerais para uma migração são estas:

  1. Adicione a dependência M3 junto com a dependência M2.
  2. Adicione as versões M3 dos temas do app junto com as versões M2 dos temas do app.
  3. Migre módulos individuais, telas ou elementos de composição para o M3, dependendo do tamanho e da complexidade do app. Nas seções abaixo você encontra mais detalhes.
  4. Após a migração, remova as versões M2 dos temas do app.
  5. Remova a dependência do M2.

Dependências

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

M2

implementation "androidx.compose.material:material:$m2-version"

M3

implementation "androidx.compose.material3:material3:$m3-version"

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

Outras dependências do Material Design fora das bibliotecas principais M2 e M3 não foram modificadas. Elas usam uma combinação de pacotes e versões do M2 e do M3, mas isso não afeta a migração. Elas podem ser usadas no estado em que se encontram com o M3:

Biblioteca Pacote e versão
Ícones do Compose Material androidx.compose.material:material-icons-*:$m2-version
Ondulações do Compose Material androidx.compose.material:material-ripple:$m2-version

APIs experimentais

Algumas APIs do M3 são consideradas experimentais. Nesses casos, vai ser necessário ativar o nível da função ou do arquivo usando a anotação ExperimentalMaterial3Api:

import androidx.compose.material3.ExperimentalMaterial3Api

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppComposable() {
    // M3 composables
}

Temas

Nas versões M2 e M3, o tema de composição é chamado de MaterialTheme, mas os pacotes e parâmetros de importação são diferentes:

M2

import androidx.compose.material.MaterialTheme

MaterialTheme(
    colors = AppColors,
    typography = AppTypography,
    shapes = AppShapes
) {
    // M2 content
}

M3

import androidx.compose.material3.MaterialTheme

MaterialTheme(
    colorScheme = AppColorScheme,
    typography = AppTypography,
    shapes = AppShapes
) {
    // M3 content
}

Cor

Comparação dos sistemas de cores M2 com M3
Figura 1. Sistema de cores M2 (à esquerda) x sistema de cores M3 (à direita).

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

M2

import androidx.compose.material.lightColors
import androidx.compose.material.darkColors

val AppLightColors = lightColors(
    // M2 light Color parameters
)
val AppDarkColors = darkColors(
    // M2 dark Color parameters
)
val AppColors = if (darkTheme) {
    AppDarkColors
} else {
    AppLightColors
}

M3

import androidx.compose.material3.lightColorScheme
import androidx.compose.material3.darkColorScheme

val AppLightColorScheme = lightColorScheme(
    // M3 light Color parameters
)
val AppDarkColorScheme = darkColorScheme(
    // M3 dark Color parameters
)
val AppColorScheme = if (darkTheme) {
    AppDarkColorScheme
} else {
    AppLightColorScheme
}

Devido às diferenças significativas entre os sistemas de cores M2 e M3, não há mapeamento razoável para os parâmetros Color. Em vez disso, use a ferramenta do criador de Temas do Material Design para gerar um esquema de cores do M3. Use as cores M2 como cores de origem principais na ferramenta, que a ferramenta expande em paletas tonais usadas pelo esquema de cores M3. Os mapeamentos abaixo são recomendados como ponto de partida:

M2 Criador de Temas do Material Design
primary Primary
primaryVariant Secundário
secondary Tertiary
surface ou background Neutral
Cores do M2 usadas no Criador de Temas do Material Design para gerar um esquema de cores do M3
Figura 2. Cores do M2 do Jetchat usadas no Material Theme Builder para gerar um esquema de cores do M3.

É possível copiar os valores de código hexadecimal de cores para os temas claro e escuro da ferramenta e usá-los para implementar uma instância ColorScheme do M3. Como alternativa, o Criador de Temas do Material Design pode exportar o código do Compose.

isLight

Ao contrário da classe Colors do M2, a classe ColorScheme do M3 não inclui um parâmetro isLight. Em geral, você precisa tentar modelar os elementos que precisarem dessas informações no nível do tema. Exemplo:

M2

import androidx.compose.material.lightColors
import androidx.compose.material.darkColors
import androidx.compose.material.MaterialTheme

@Composable
private fun AppTheme(
  darkTheme: Boolean = isSystemInDarkTheme(),
  content: @Composable () -> Unit
) {
  val colors = if (darkTheme) darkColors() else lightColors()
  MaterialTheme(
      colors = colors,
      content = content
  )
}

@Composable
fun AppComposable() {
    AppTheme {
        val cardElevation = if (MaterialTheme.colors.isLight) 0.dp else 4.dp
        
    }
}

M3

import androidx.compose.material3.lightColorScheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.MaterialTheme

val LocalCardElevation = staticCompositionLocalOf { Dp.Unspecified }
@Composable
private fun AppTheme(
   darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {
   val cardElevation = if (darkTheme) 4.dp else 0.dp
    CompositionLocalProvider(LocalCardElevation provides cardElevation) {
        val colorScheme = if (darkTheme) darkColorScheme() else lightColorScheme()
        MaterialTheme(
            colorScheme = colorScheme,
            content = content
        )
    }
}

@Composable
fun AppComposable() {
    AppTheme {
        val cardElevation = LocalCardElevation.current
        
    }
}

Consulte o guia de sistemas de design personalizados no Compose para mais informações.

Cores dinâmicas

Um novo recurso do M3 é a cor dinâmica (link em inglês). Em vez de usar cores personalizadas, um ColorScheme do M3 pode usar as cores do plano de fundo do dispositivo no Android 12 e versões mais recentes, usando estas funções:

Tipografia

Comparação dos sistemas de tipografia M2 e M3
Figura 3. Sistema de tipografia M3 (à esquerda) x sistema de tipografia M2 (à direita)

O sistema de tipografia (link em inglês) do M3 é diferente do M2. O número de parâmetros de tipografia é aproximadamente o mesmo, mas eles têm nomes diferentes e são mapeados de maneira diferente dos componentes do M3. No Compose, isso se aplica às classes Typography do M2 e à classe Typography do M3:

M2

import androidx.compose.material.Typography

val AppTypography = Typography(
    // M2 TextStyle parameters
)

M3

import androidx.compose.material3.Typography

val AppTypography = Typography(
    // M3 TextStyle parameters
)

Os mapeamentos de parâmetro TextStyle abaixo são recomendados como ponto de partida:

M2 M3
h1 displayLarge
h2 displayMedium
h3 displaySmall
N/A headlineLarge
h4 headlineMedium
h5 headlineSmall
h6 titleLarge
subtitle1 titleMedium
subtitle2 titleSmall
body1 bodyLarge
body2 bodyMedium
caption bodySmall
button labelLarge
N/A labelMedium
overline labelSmall

Forma

Comparação dos sistemas de formas M2 e M3
Figura 4. Sistema de formas do M2 (à esquerda) x sistema de formas do M3 (à direita)

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 dos componentes do M3. No Compose, isso se aplica à classe Shapes do M2 e à classe Shapes do M3:

M2

import androidx.compose.material.Shapes

val AppShapes = Shapes(
    // M2 Shape parameters
)

M3

import androidx.compose.material3.Shapes

val AppShapes = Shapes(
    // M3 Shape parameters
)

Os mapeamentos de parâmetro Shape abaixo são recomendados como ponto de partida:

M2 M3
N/A extraSmall
small small
medium medium
large large
N/A extraLarge

Componentes e layouts

A maioria dos componentes e layouts do M2 está disponível no M3. No entanto, alguns estão ausentes e outros são novos e não existiam no M2. Além disso, alguns componentes do M3 têm mais variações do que os equivalentes no M2. Em geral, as superfícies da API M3 tentam ser o mais semelhante possível aos equivalentes mais próximos no M2.

Considerando os sistemas de cor, tipografia e forma atualizados, os componentes do M3 tendem a ser mapeados de maneira diferente dos novos valores de tema. É recomendável conferir o diretório de tokens no código-fonte do Compose Material 3 como uma fonte de verdade para esses mapeamentos.

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

APIs ausentes:

M2 M3
androidx.compose.material.swipeable Ainda não disponível

APIs substituídas:

M2 M3
androidx.compose.material.BackdropScaffold Nenhum equivalente do M3. Migre para o Scaffold ou o BottomSheetScaffold
androidx.compose.material.BottomDrawer Sem equivalente do M3, migre para ModalBottomSheet

APIs renomeadas:

M2 M3
androidx.compose.material.BottomNavigation androidx.compose.material3.NavigationBar
androidx.compose.material.BottomNavigationItem androidx.compose.material3.NavigationBarItem
androidx.compose.material.Chip androidx.compose.material3.AssistChip ou androidx.compose.material3.SuggestionChip
androidx.compose.material.ModalBottomSheetLayout androidx.compose.material3.ModalBottomSheet
androidx.compose.material.ModalDrawer androidx.compose.material3.ModalNavigationDrawer

Todas as outras APIs:

M2 M3
androidx.compose.material.AlertDialog androidx.compose.material3.AlertDialog
androidx.compose.material.Badge androidx.compose.material3.Badge
androidx.compose.material.BadgedBox androidx.compose.material3.BadgedBox
androidx.compose.material.BottomAppBar androidx.compose.material3.BottomAppBar
androidx.compose.material.BottomSheetScaffold androidx.compose.material3.BottomSheetScaffold
androidx.compose.material.Button androidx.compose.material3.Button
androidx.compose.material.Card androidx.compose.material3.Card
androidx.compose.material.Checkbox androidx.compose.material3.Checkbox
androidx.compose.material.CircularProgressIndicator androidx.compose.material3.CircularProgressIndicator
androidx.compose.material.Divider androidx.compose.material3.Divider
androidx.compose.material.DropdownMenu androidx.compose.material3.DropdownMenu
androidx.compose.material.DropdownMenuItem androidx.compose.material3.DropdownMenuItem
androidx.compose.material.ExposedDropdownMenuBox androidx.compose.material3.ExposedDropdownMenuBox
androidx.compose.material.ExtendedFloatingActionButton androidx.compose.material3.ExtendedFloatingActionButton
androidx.compose.material.FilterChip androidx.compose.material3.FilterChip
androidx.compose.material.FloatingActionButton androidx.compose.material3.FloatingActionButton
androidx.compose.material.Icon androidx.compose.material3.Icon
androidx.compose.material.IconButton androidx.compose.material3.IconButton
androidx.compose.material.IconToggleButton androidx.compose.material3.IconToggleButton
androidx.compose.material.LeadingIconTab androidx.compose.material3.LeadingIconTab
androidx.compose.material.LinearProgressIndicator androidx.compose.material3.LinearProgressIndicator
androidx.compose.material.ListItem androidx.compose.material3.ListItem
androidx.compose.material.NavigationRail androidx.compose.material3.NavigationRail
androidx.compose.material.NavigationRailItem androidx.compose.material3.NavigationRailItem
androidx.compose.material.OutlinedButton androidx.compose.material3.OutlinedButton
androidx.compose.material.OutlinedTextField androidx.compose.material3.OutlinedTextField
androidx.compose.material.RadioButton androidx.compose.material3.RadioButton
androidx.compose.material.RangeSlider androidx.compose.material3.RangeSlider
androidx.compose.material.Scaffold androidx.compose.material3.Scaffold
androidx.compose.material.ScrollableTabRow androidx.compose.material3.ScrollableTabRow
androidx.compose.material.Slider androidx.compose.material3.Slider
androidx.compose.material.Snackbar androidx.compose.material3.Snackbar
androidx.compose.material.Switch androidx.compose.material3.Switch
androidx.compose.material.Tab androidx.compose.material3.Tab
androidx.compose.material.TabRow androidx.compose.material3.TabRow
androidx.compose.material.Text androidx.compose.material3.Text
androidx.compose.material.TextButton androidx.compose.material3.TextButton
androidx.compose.material.TextField androidx.compose.material3.TextField
androidx.compose.material.TopAppBar androidx.compose.material3.TopAppBar
androidx.compose.material.TriStateCheckbox androidx.compose.material3.TriStateCheckbox

Consulte os componentes e layouts mais recentes do M3 na Visão geral da Referência da API Compose Material 3 e fique de olho na página de lançamentos para APIs novas e atualizadas.

Scaffold, snackbars e gaveta de navegação

Comparação do scaffold do M2 e M3 com snackbar e gaveta de navegação
Figura 5. Scaffold do M2 com snackbar e gaveta de navegação (à esquerda) x scaffold do M3 com snackbar e gaveta de navegação (à direita).

O Scaffold no M3 é diferente do M2. Nas versões M2 e M3, o principal elemento combinável de layout é chamado Scaffold, mas os pacotes e parâmetros de importação são diferentes:

M2

import androidx.compose.material.Scaffold

Scaffold(
    // M2 scaffold parameters
)

M3

import androidx.compose.material3.Scaffold

Scaffold(
    // M3 scaffold parameters
)

O Scaffold do M2 que contém um parâmetro backgroundColor agora é chamado de containerColor no Scaffold do M3:

M2

import androidx.compose.material.Scaffold

Scaffold(
    backgroundColor = ,
    content = {  }
)

M3

import androidx.compose.material3.Scaffold

Scaffold(
    containerColor = ,
    content = {  }
)

A classe ScaffoldState do M2 não existe mais no M3 porque contém um parâmetro drawerState que não é mais necessário. Para mostrar snackbars com o Scaffold do M3, use SnackbarHostState:

M2

import androidx.compose.material.Scaffold
import androidx.compose.material.rememberScaffoldState

val scaffoldState = rememberScaffoldState()
val scope = rememberCoroutineScope()

Scaffold(
    scaffoldState = scaffoldState,
    content = {
        
        scope.launch {
            scaffoldState.snackbarHostState.showSnackbar()
        }
    }
)

M3

import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState

val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()

Scaffold(
    snackbarHost = { SnackbarHost(snackbarHostState) },
    content = {
        
        scope.launch {
            snackbarHostState.showSnackbar()
        }
    }
)

Todos os parâmetros drawer* do Scaffold do M2 foram removidos do Scaffold do M3. Isso inclui parâmetros como drawerShape e drawerContent. Para mostrar uma gaveta com o Scaffold do M3, use um elemento combinável de gaveta de navegação, como ModalNavigationDrawer:

M2

import androidx.compose.material.DrawerValue
import
import androidx.compose.material.Scaffold
import androidx.compose.material.rememberDrawerState
import androidx.compose.material.rememberScaffoldState

val scaffoldState = rememberScaffoldState(
    drawerState = rememberDrawerState(DrawerValue.Closed)
)
val scope = rememberCoroutineScope()

Scaffold(
    scaffoldState = scaffoldState,
    drawerContent = {  },
    drawerGesturesEnabled = ,
    drawerShape = ,
    drawerElevation = ,
    drawerBackgroundColor = ,
    drawerContentColor = ,
    drawerScrimColor = ,
    content = {
        
        scope.launch {
            scaffoldState.drawerState.open()
        }
    }
)

M3

import androidx.compose.material3.DrawerValue
import androidx.compose.material3.ModalDrawerSheet
import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.material3.Scaffold
import androidx.compose.material3.rememberDrawerState

val drawerState = rememberDrawerState(DrawerValue.Closed)
val scope = rememberCoroutineScope()

ModalNavigationDrawer(
    drawerState = drawerState,
    drawerContent = {
        ModalDrawerSheet(
            drawerShape = ,
            drawerTonalElevation = ,
            drawerContainerColor = ,
            drawerContentColor = ,
            content = {  }
        )
    },
    gesturesEnabled = ,
    scrimColor = ,
    content = {
        Scaffold(
            content = {
                
                scope.launch {
                    drawerState.open()
                }
            }
        )
    }
)

Barra de apps superior

Comparação do scaffold do M2 e M3 com a barra de apps superior e a lista de rolagem
Figura 6. Scaffold do M2 com a barra de apps superior e a lista de rolagem (à esquerda) x scaffold do M3 com a barra de apps superior e a lista de rolagem (à direita)

As principais barras de apps (link em inglês) no M3 são diferentes das usadas no M2. No M2 e no M3, o principal elemento combinável da barra de apps principal é chamado de TopAppBar, mas os pacotes e parâmetros de importação são diferentes:

M2

import androidx.compose.material.TopAppBar

TopAppBar()

M3

import androidx.compose.material3.TopAppBar

TopAppBar()

Considere usar o CenterAlignedTopAppBar do M3 se já estiver centralizando o conteúdo no TopAppBar do M2. Também é bom conhecer o MediumTopAppBar e o LargeTopAppBar.

As principais barras de apps do M3 contêm um novo parâmetro scrollBehavior para fornecer diferentes funcionalidades de rolagem pela classe TopAppBarScrollBehavior, como mudança da elevação. Isso funciona junto com a rolagem de conteúdo usando Modifer.nestedScroll. Isso foi possível no TopAppBar do M2 mudando manualmente o parâmetro elevation:

M2

import androidx.compose.material.AppBarDefaults
import androidx.compose.material.Scaffold
import androidx.compose.material.TopAppBar

val state = rememberLazyListState()
val isAtTop by remember {
    derivedStateOf {
        state.firstVisibleItemIndex == 0 && state.firstVisibleItemScrollOffset == 0
    }
}

Scaffold(
    topBar = {
        TopAppBar(
            elevation = if (isAtTop) {
                0.dp
            } else {
                AppBarDefaults.TopAppBarElevation
            },
            
        )
    },
    content = {
        LazyColumn(state = state) {  }
    }
)

M3

import androidx.compose.material3.Scaffold
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults

val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()

Scaffold(
    modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
    topBar = {
        TopAppBar(
            scrollBehavior = scrollBehavior,
            
        )
    },
    content = {
        LazyColumn {  }
    }
)

Navegação inferior/barra de navegação

Comparação entre a navegação inferior do M2 e a barra de navegação do M3
Figura 7. Navegação na parte de baixo do M2 (à esquerda) x barra de navegação do M3 (à direita).

A navegação inferior no M2 foi renomeada como barra de navegação (link em inglês) no M3. O M2 usa os elementos combináveis BottomNavigation e BottomNavigationItem. O M3 usa os elementos combináveis NavigationBar e NavigationBarItem:

M2

import androidx.compose.material.BottomNavigation
import androidx.compose.material.BottomNavigationItem

BottomNavigation {
    BottomNavigationItem()
    BottomNavigationItem()
    BottomNavigationItem()
}

M3

import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem

NavigationBar {
    NavigationBarItem()
    NavigationBarItem()
    NavigationBarItem()
}

Botões, botões de ícone e FABs

Comparação dos botões do M2 e M3
Figura 8. Botões do M2 (à esquerda) x botões do M3 (à direita)

Botões, botões de ícone e botões de ação flutuante (FABs) (link em inglês) no M3 são diferentes dos botões no M2. O M3 inclui todos os elementos combináveis do botão do M2:

M2

import androidx.compose.material.Button
import androidx.compose.material.ExtendedFloatingActionButton
import androidx.compose.material.FloatingActionButton
import androidx.compose.material.IconButton
import androidx.compose.material.IconToggleButton
import androidx.compose.material.OutlinedButton
import androidx.compose.material.TextButton

// M2 buttons
Button()
OutlinedButton()
TextButton()
// M2 icon buttons
IconButton()
IconToggleButton()
// M2 FABs
FloatingActionButton()
ExtendedFloatingActionButton()

M3

import androidx.compose.material3.Button
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconToggleButton
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.TextButton

// M3 buttons
Button()
OutlinedButton()
TextButton()
// M3 icon buttons
IconButton()
IconToggleButton()
// M3 FABs
FloatingActionButton()
ExtendedFloatingActionButton()

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

Chave

Comparação entre chaves do M2 e M3
Figura 9. Chave do M2 (à esquerda) x da chave do M3 (à direita).

A chave (link em inglês) no M3 é diferente do M2. Tanto no M2 quanto no M3, a chave de composição é chamada de Switch, mas os pacotes de importação são diferentes:

M2

import androidx.compose.material.Switch

Switch()

M3

import androidx.compose.material3.Switch

Switch()

Superfícies e elevação

Comparação entre elevação de superfície do M2 e elevação de superfície do M3 em temas claros e escuros
Figura 10. Elevação da superfície do M2 em relação à elevação da superfície do M3 no tema claro (à esquerda) e no tema escuro (à direita).

Os sistemas de superfície e elevação no M3 são diferentes do M2. Há dois tipos de elevação no M3:

  • Elevação da sombra (gera uma sombra, igual à do M2)
  • Elevação de tonalidade (sobreposição de uma cor, novidade do M3)

No Compose, isso se aplica às funções Surface do M2 e Surface do M3:

M2

import androidx.compose.material.Surface

Surface(
    elevation = 
) {  }

M3

import androidx.compose.material3.Surface

Surface(
    shadowElevation = ,
    tonalElevation = 
) {  }

Você pode usar os valores Dp do elevation no M2 para shadowElevation e/ou tonalElevation no M3, dependendo da preferência de design da UX/IU. O Surface é o elemento de apoio da maioria dos componentes. Os elementos combináveis também podem expor parâmetros de elevação que precisam ser migrados da mesma forma.

A elevação de tons no M3 substitui o conceito de sobreposições de elevação em temas escuros M2. Como resultado, ElevationOverlay e LocalElevationOverlay não existem no M3, e LocalAbsoluteElevation do M2 mudou para LocalAbsoluteTonalElevation no M3.

Ênfase e conteúdo Alfa

Comparação dos ícones M2 e M3 com ênfase no texto
Figura 11. Ícone e ênfase no texto do M2 (à esquerda) x ícone e ênfase no texto do M3 (à direita)

A ênfase no M3 é significativamente diferente do M2. No M2, a ênfase envolvia o uso de cores on com determinados valores Alfa para diferenciar conteúdo como texto e ícones. No M3, agora existem algumas abordagens diferentes:

  • Usando cores on com as cores variante on do sistema de cores expandido do M3.
  • Usar diferentes pesos de fonte para texto.

Como resultado, ContentAlpha e LocalContentAlpha não existem no M3 e precisam ser substituídos.

Os mapeamentos abaixo são recomendados como ponto de partida:

M2 M3
onSurface por ContentAlpha.high onSurface em geral, FontWeight.Medium - FontWeight.Black para texto
onSurface por ContentAlpha.medium onSurfaceVariant em geral, FontWeight.Thin - FontWeight.Normal para texto
onSurface por ContentAlpha.disabled onSurface.copy(alpha = 0.38f)

Confira um exemplo de ênfase de ícones no M2 e no M3:

M2

import androidx.compose.material.ContentAlpha
import androidx.compose.material.LocalContentAlpha

// High emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.high) {
    Icon()
}
// Medium emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
    Icon()
}
// Disabled emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.disabled) {
    Icon()
}

M3

import androidx.compose.material3.LocalContentColor

// High emphasis
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface) {
    Icon()
}
// Medium emphasis
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurfaceVariant) {
    Icon()
}
// Disabled emphasis
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f)) {
    Icon()
}

Confira exemplos de ênfase no texto no M2 e M3:

M2

import androidx.compose.material.ContentAlpha
import androidx.compose.material.LocalContentAlpha

// High emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.high) {
    Text()
}
// Medium emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
    Text()
}
// Disabled emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.disabled) {
    Text()
}

M3

import androidx.compose.material3.LocalContentColor

// High emphasis
Text(
    ,
    fontWeight = FontWeight.Bold
)
// Medium emphasis
Text(
    ,
    fontWeight = FontWeight.Normal
)
// Disabled emphasis
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f)) {
    Text(
        ,
        fontWeight = FontWeight.Normal
    )
}

Planos de fundo e contêineres

Os planos de fundo no M2 são contêineres nomeados no M3. Em geral, é possível substituir os parâmetros background* no M2 por container* no M3, usando os mesmos valores. Exemplo:

M2

Badge(
    backgroundColor = MaterialTheme.colors.primary
) {  }

M3

Badge(
    containerColor = MaterialTheme.colorScheme.primary
) {  }

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

Documentos

Apps de exemplo

Vídeos

Referência da API e código-fonte