Cómo migrar de Material 2.5 a Material 3 en Compose para Wear OS

Material 3 expresivo es la siguiente evolución de Material Design. Incluye temas y componentes actualizados, y funciones de personalización de Material You, como el color dinámico.

Esta guía se enfoca en la migración de la biblioteca de Jetpack Wear Compose Material 2.5 (androidx.wear.compose) a la biblioteca de Jetpack Wear Compose Material 3 (androidx.wear.compose.material3) para apps.

Enfoques

Para migrar el código de tu app de M2.5 a M3, sigue el mismo enfoque que se describe en la guía de migración de teléfonos de Material de Compose, en particular:

Dependencias

M3 tiene un paquete y una versión diferentes a M2.5:

M2.5

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

M3

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

Consulta las versiones más recientes de M3 en la página de versiones de Wear Compose Material 3.

La versión 1.5.0-beta01 de la biblioteca de Wear Compose Foundation presenta algunos componentes nuevos diseñados para funcionar con componentes de Material 3. Del mismo modo, SwipeDismissableNavHost de la biblioteca de navegación de Wear Compose tiene una animación actualizada cuando se ejecuta en Wear OS 6 (nivel de API 36) o versiones posteriores. Cuando actualices a la versión de Material 3 de Wear Compose, te recomendamos que también actualices las bibliotecas de Navigation y Foundation de Wear Compose:

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

Temas

En M2.5 y M3, el tema que admite composición se denomina MaterialTheme, pero los paquetes de importación y los parámetros difieren. En M3, el parámetro Colors se renombró a ColorScheme y se introdujo MotionScheme para implementar transiciones.

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
)

Color

El sistema de colores de M3 es significativamente diferente al de M2.5. La cantidad de parámetros de color aumentó, tienen nombres diferentes y se asignan de forma distinta a los componentes de M3. En Compose, esto se aplica a la clase Colors de M2.5, la clase ColorScheme de M3 y las funciones 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
)

En la siguiente tabla, se describen las diferencias clave entre M2.5 y M3:

M2.5

M3

Color

Se cambió el nombre de ColorScheme por ColorScheme.

13 colores

28 colores

N/A

Nuevos temas de colores dinámicos

N/A

Nuevos colores terciarios para mayor expresión

Temas de colores dinámicos

Una nueva función de M3 es el tema de colores dinámicos. Si los usuarios cambian los colores de la cara de reloj, los colores de la IU cambian para que coincidan.

Usa la función dynamicColorScheme para implementar el esquema de colores dinámico y proporcionar un defaultColorScheme como resguardo en caso de que el esquema de colores dinámico no esté disponible.

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

Tipografía

El sistema de tipografía en M3 es diferente al de M2 y, además, incluye las siguientes funciones:

  • Nueve estilos de texto nuevos
  • Fuentes Flex, que permiten personalizar las escalas de tipo para diferentes grosores, anchos y redondeces
  • AnimatedText, que usa fuentes flexibles

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
)

Fuentes Flex

Las fuentes Flex permiten a los diseñadores especificar el ancho y el grosor del tipo para tamaños específicos.

Estilos de texto

Los siguientes TextStyles están disponibles en M3. Varios componentes de M3 los usan de forma predeterminada.

Tipografía

TextStyle

Pantalla

displayLarge, displayMedium, displaySmall

Título

titleLarge, titleMedium, titleSmall

Etiqueta

labelLarge, labelMedium, labelSmall

Cuerpo

bodyLarge, bodyMedium, bodySmall, bodyExtraSmall

Numeral

numeralExtraLarge, numeralLarge, numeralMedium, numeralSmall, numeralExtraSmall

Arc

arcLarge, arcMedium, arcSmall

Forma

El sistema de forma en M3 es diferente al de M2. La cantidad de parámetros de forma aumentó, tienen nombres diferentes y se asignan, de forma distinta, a los componentes de M3. Los siguientes tamaños de formas están disponibles:

  • Extrapequeño
  • Pequeño
  • Mediano
  • Grande
  • Extragrande

En Compose, esto se aplica a la clase Shapes de M2 y a la clase Shapes de 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
)

Usa la asignación de parámetros de formas de Cómo migrar de Material 2 a Material 3 en Compose como punto de partida.

Transformación de formas

M3 presenta la transformación de formas: las formas ahora se transforman en respuesta a las interacciones.

El comportamiento de transformación de forma está disponible como una variación en varios botones redondos. Consulta a continuación:

Botones

Función de transformación de forma

IconButton

IconButtonDefaults.animatedShape() anima el botón de ícono cuando se presiona.

IconToggleButton

IconToggleButtonDefaults.animatedShape() anima el botón de activación de íconos cuando se presiona.

IconToggleButtonDefaults.variantAnimatedShapes() anima el botón de activación de íconos cuando se presiona y marca o desmarca.

TextButton

TextButtonDefaults.animatedShape() anima el botón de texto cuando se presiona.

TextToggleButton

TextToggleButtonDefaults.animatedShapes() anima el botón de activación de texto cuando se presiona, y TextToggleButtonDefaults.variantAnimatedShapes() anima el botón de activación de texto cuando se presiona y se marca o desmarca.

Componentes y diseño

La mayoría de los componentes y diseños de M2.5 están disponibles en M3. Sin embargo, algunos componentes y diseños de M3 no existían en M2.5. Además, algunos componentes de M3 tienen más variaciones que sus equivalentes en M2.5.

Si bien algunos componentes requieren consideraciones especiales, se recomiendan las siguientes asignaciones de funciones como punto 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 o 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

No hay un equivalente en M3. Migra a androidx.wear.compose.material3.CheckboxButton o androidx.wear.compose.material3.SplitCheckboxButton.

androidx.wear.compose.material.Chip

androidx.wear.compose.material3.Button o
androidx.wear.compose.material3.OutlinedButton o
androidx.wear.compose.material3.FilledTonalButton o
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

Se quitó porque Text o Icon no lo usan en Material 3

androidx.wear.compose.material.PositionIndicator

androidx.wear.compose.material3.ScrollIndicator

androidx.wear.compose.material.RadioButton

No hay un equivalente en M3. Migra a androidx.wear.compose.material3.RadioButton o 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 y androidx.wear.compose.material3.ScreenScaffold

androidx.wear.compose.material.SplitToggleChip

No hay un equivalente de M3. Migra a androidx.wear.compose.material3.SplitCheckboxButton, androidx.wear.compose.material3.SplitSwitchButton o androidx.wear.compose.material3.SplitRadioButton.

androidx.wear.compose.material.Switch

No hay un equivalente de M3. Migra a androidx.wear.compose.material3.SwitchButton o androidx.wear.compose.material3.SplitSwitchButton.

androidx.wear.compose.material.ToggleButton

androidx.wear.compose.material3.IconToggleButton o androidx.wear.compose.material3.TextToggleButton

androidx.wear.compose.material.ToggleChip

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

androidx.wear.compose.material.Vignette

Se quitó porque no se incluye en el diseño expresivo de Material 3 para Wear OS.

Esta es una lista completa de todos los componentes de Material 3:

Material 3

Componente equivalente a Material 2.5 (si no es nuevo en M3)

androidx.wear.compose.material3.AlertDialog

androidx.wear.compose.material.dialog.Alert

androix.wear.compose.material3.AnimatedPage

Novedades

androidx.wear.compose.material3.AnimatedText

Novedades

androidx.wear.compose material3.AppScaffold

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

androidx.wear.compose.material3.Button

androidx.wear.compose.material.Chip

androidx.wear.compose.material3.ButtonGroup

Novedades

androidx.wear.compose.material3.Card

androidx.wear.compose.material.Card

androidx.wear.compose.material3.CheckboxButton

androidx.wear.compose.material.ToggleChip con un control de activación de casilla de verificación

androidx.wear.compose.material3.ChildButton

androidx.wear.compose.material.Chip (solo cuando no se requiere un fondo)

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

Novedades

androidx.wear.compose.material3.Dialog

androidx.wear.compose.material.dialog.Dialog

androidx.wear.compose.material3.EdgeButton

Novedades

androidx.wear.compose.material3.FadingExpandingLabel

Novedades

androidx.wear.compose.material3.FilledTonalButton

androidx.wear.compose.material.Chip cuando se requiere un fondo de botón tonal

androidx.wear.compose.material3.HorizontalPageIndicator

androidx.wear.compose.material.HorizontalPageIndicator

androidx.wear.compose.material3.HorizontalPagerScaffold

Novedades

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

Novedades

androidx.wear.compose.material3.LinearProgressIndicator

Novedades

androidx.wear.compose.material3.ListHeader

androidx.wear.compose.material.ListHeader

androidx.wear.compose.material3.ListSubHeader

Novedades

androidx.wear.compose.material3.MaterialTheme

androidx.wear.compose.material.MaterialTheme

androidx.wear.compose.material3.OpenOnPhoneDialog

Novedades

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 con un control de activación de botón de selección

androidx.wear.compose.material3.ScreenScaffold

android.wear.compose.material.Scaffold (con 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

Novedades

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 y androidx.wear.compose.material.SwipeToRevealChip

androidx.wear.compose.material3.SwitchButton

androidx.wear.compose.material.ToggleChip con un control de interruptor

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

Novedades

Por último, una lista de algunos componentes relevantes de la biblioteca de Wear Compose Foundation versión 1.5.0-beta01:

Wear Compose Foundation 1.5.0-beta

androidx.wear.compose.foundation.hierarchicalFocusGroup

Se usa para anotar elementos componibles en una aplicación, para hacer un seguimiento de la parte activa de la composición y coordinar el enfoque.

androidx.compose.foundation.pager.HorizontalPager

Un selector de paginación con desplazamiento horizontal, compilado en los componentes de Compose Foundation con mejoras específicas para Wear que mejoran el rendimiento y el cumplimiento de los lineamientos de Wear OS.

androidx.compose.foundation.pager.VerticalPager

Un selector de páginas con desplazamiento vertical, compilado en los componentes de Compose Foundation con mejoras específicas para Wear para mejorar el rendimiento y el cumplimiento de los lineamientos de Wear OS.

androidx.wear.foundation.lazy.TransformingLazyColumn

Se puede usar en lugar de ScalingLazyColumn para agregar efectos de transformación de desplazamiento a cada elemento.

Botones

Los botones de M3 son diferentes a los de M2.5. El chip M2.5 se reemplazó por el botón. La implementación de Button proporciona valores predeterminados para Text, maxLines y textAlign. Esos valores predeterminados se pueden anular en el 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(...)

M3 también incluye nuevas variaciones de botones. Consulta la descripción general de la referencia de la API de Compose Material 3.

M3 presenta un nuevo botón: EdgeButton. EdgeButton está disponible en 4 tamaños diferentes: extrapequeño, pequeño, mediano y grande. La implementación de EdgeButton proporciona un valor predeterminado para maxLines según el tamaño que se puede personalizar.

Si usas TransformingLazyColumn y ScalingLazyColumn, pasa el EdgeButton a ScreenScaffold para que se transforme y cambie de forma con el desplazamiento. Consulta el siguiente código para ver cómo usar EdgeButton con ScreenScaffold y 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

El andamiaje en M3 es diferente al de M2.5. En M3, AppScaffold y el nuevo elemento componible ScreenScaffold reemplazaron a Scaffold. AppScaffold y ScreenScaffold diseñan la estructura de una pantalla y coordinan las transiciones de los componentes ScrollIndicator y TimeText.

AppScaffold permite que los elementos de pantalla estáticos, como TimeText, permanezcan visibles durante las transiciones en la app, como el deslizamiento para descartar. ​​Proporciona un espacio para el contenido principal de la aplicación, que suele proporcionar un componente de navegación, como SwipeDismissableNavHost.

Declaras un AppScaffold para la actividad y usas un ScreenScaffold para cada pantalla.

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
    }
}

Si usas un HorizontalPager con HorizontalPagerIndicator, puedes migrar a HorizontalPagerScaffold. HorizontalPagerScaffold se coloca dentro de un AppScaffold. AppScaffold y HorizontalPagerScaffold diseñan la estructura de un objeto Pager y coordinan las transiciones de los componentes HorizontalPageIndicator y TimeText.

HorizontalPagerScaffold muestra el HorizontalPageIndicator en el centro de la pantalla de forma predeterminada y coordina la ocultación o visualización de TimeText y HorizontalPageIndicator según si se pagina Pager, lo que determina PagerState.

También hay un nuevo componente AnimatedPage, que anima una página dentro de un objeto Pager con un efecto de escalamiento y pantalla en función de su posición.

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 último, M3 presenta un VerticalPagerScaffold que sigue el mismo patrón que 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 posición

Hay algunos cambios en la API entre la versión 2.5 y la 3. Placeholder.PlaceholderDefaults ahora proporciona dos modificadores:

  • Modifier.placeholder, que se dibuja en lugar del contenido que aún no se cargó
  • Un efecto de brillo del marcador de posición Modifier.placeholderShimmer que proporciona un efecto de brillo del marcador de posición que se ejecuta en un bucle de animación mientras se espera que se carguen los datos.

Consulta a continuación los cambios adicionales en el componente Placeholder.

M2.5

M3

PlaceholderState.startPlaceholderAnimation

Se quitó

PlaceholderState.placeholderProgression

Se quitó

PlaceholderState.isShowContent

Se cambió el nombre a !PlaceholderState.isVisible.

PlaceholderState.isWipeOff

Se quitó

PlaceholderDefaults.painterWithPlaceholderOverlayBackgroundBrush

se quitó

PlaceholderDefaults.placeholderBackgroundBrush

Se quitó

PlaceholderDefaults.placeholderChipColors

Se quitó

SwipeDismissableNavHost

SwipeDismissableNavHost es parte de wear.compose.navigation. Cuando se usa este componente con M3, MaterialTheme de M3 actualiza LocalSwipeToDismissBackgroundScrimColor y LocalSwipeToDismissContentScrimColor.

TransformingLazyColumn

TransformingLazyColumn forma parte de wear.compose.lazy.foundation y agrega compatibilidad con animaciones de escalamiento y transformación en elementos de lista durante el desplazamiento, lo que mejora la experiencia del usuario.

Al igual que ScalingLazyColumn, proporciona rememberTransformingLazyColumnState() para crear un TransformingLazyColumnState que se recuerda en todas las composiciones.

Para agregar animaciones de escalamiento y transformación, agrega lo siguiente a cada elemento de la lista:

  • Modifier.transformedHeight, que te permite calcular la altura transformada de los elementos con un TransformationSpec, puedes usar rememberTransformationSpec(), a menos que necesites más personalización.
  • Un 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")
                    }
                }
            }
        }
    }

Vínculos útiles

Para obtener más información sobre la migración de M2.5 a M3 en Compose, consulta los siguientes recursos adicionales.

Ejemplos

Ejemplos de Wear OS en la rama Material3 en GitHub

Codelab de Compose para Wear OS

Referencia de la API y código fuente

Diseño