Material 3 Expressive es la siguiente evolución de Material Design. Incluye temas, componentes y funciones de personalización actualizados, como el color dinámico.
En esta guía, se explica cómo migrar de la biblioteca de Wear Compose Material 2.5 (androidx.wear.compose) Jetpack a la biblioteca de Wear Compose Material 3 (androidx.wear.compose.material3) Jetpack 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 para teléfonos sobre la migración de Compose Material, en particular:
- No deberías usar M2.5 y M3 en una sola app a largo plazo
- Adopta un enfoque por fases
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.6.0-alpha04")
Consulta las versiones más recientes de M3 en la página de versiones de Wear Compose Material 3.
La versión 1.6.0-alpha04 de la biblioteca de Wear Compose Foundation introdujo algunos componentes nuevos diseñados para funcionar con los componentes de Material 3.
Del mismo modo, SwipeDismissableNavHost de la biblioteca de Wear Compose Navigation 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 Wear Compose Material 3, te sugerimos que también actualices las bibliotecas de Wear Compose Foundation y Navigation:
implementation("androidx.wear.compose:compose-foundation:1.6.0-alpha04")
implementation("androidx.wear.compose:compose-navigation:1.6.0-alpha04")
Tema
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, se cambió el nombre del parámetro Colors 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 color en 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 |
|---|---|
|
Se cambió el nombre a |
13 colores |
28 colores |
N/A |
Nuevo tema de color dinámico |
N/A |
Nuevos colores terciarios para una mayor expresión |
Tematización con color dinámico
Una nueva función de M3 es el tema de color dinámico. Si los usuarios cambian los colores de la cara del reloj, los colores de la IU también cambiarán 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 nuevos estilos de texto
- Fuentes flexibles, que permiten personalizar las escalas de escritura para diferentes pesos, anchos y redondez
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 flexibles
Las fuentes flexibles 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. Los diversos componentes de M3 los emplean 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 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 introduce el cambio de forma: Las formas ahora cambian en respuesta a las interacciones.
El comportamiento de transformación de formas está disponible como una variación en varios botones redondos. Consulta la siguiente lista de botones que admiten la transformación de formas:
Botones |
Función de transformación de formas |
|---|---|
|
IconButtonDefaults.animatedShape() anima el botón de ícono cuando se presiona |
|
IconToggleButtonDefaults.animatedShape() anima el botón de alternancia de ícono cuando se presiona y IconToggleButtonDefaults.variantAnimatedShapes() anima el botón de activación de ícono al presionarlo y marcarlo o desmarcarlo. |
|
TextButtonDefaults.animatedShape() anima el botón de texto cuando se presiona. |
|
TextToggleButtonDefaults.animatedShapes() anima el botón de alternancia de texto al presionarlo, y TextToggleButtonDefaults.variantAnimatedShapes() anima el botón de alternancia de texto al presionarlo y marcarlo o desmarcarlo. |
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:
Esta es una lista completa de todos los componentes de Material 3:
Material 3 |
Componente equivalente de Material 2.5 (si no es nuevo en M3) |
|---|---|
Novedades |
|
Novedades |
|
android.wear.compose.material.Scaffold (con androidx.wear.compose.material3.ScreenScaffold) |
|
Novedades |
|
androidx.wear.compose.material.ToggleChip con un control de activación de casilla de verificación |
|
androidx.wear.compose.material.Chip (solo cuando no se requiere un fondo) |
|
Novedades |
|
Novedades |
|
Novedades |
|
androidx.wear.compose.material.Chip cuando se requiere un fondo de botón tonal |
|
Novedades |
|
Novedades |
|
Novedades |
|
Novedades |
|
Novedades |
|
androidx.wear.compose.material.ToggleChip con un control de activación de botón de selección |
|
android.wear.compose.material.Scaffold (con androidx.wear.compose material3.AppScaffold) |
|
androidx.wear.compose.material3.SegmentedCircularProgressIndicator |
Novedades |
androidx.wear.compose.material.SwipeToRevealCard y androidx.wear.compose.material.SwipeToRevealChip |
|
androidx.wear.compose.material.ToggleChip con un control de activación de interruptor |
|
Novedades |
Por último, una lista de algunos componentes relevantes de la biblioteca de Wear Compose Foundation, que se introdujo por primera vez en la versión 1.6.0-alpha04:
Wear Compose Foundation 1.6.0-alpha04 |
|
|---|---|
Se usa para anotar elementos componibles en una aplicación, hacer un seguimiento de la parte activa de la composición y coordinar el enfoque. |
|
Es un paginador de desplazamiento horizontal, creado sobre los componentes de Compose Foundation con mejoras específicas para Wear que permiten mejorar el rendimiento y el cumplimiento de los lineamientos de Wear OS. |
|
Es un paginador de desplazamiento vertical, creado sobre los componentes de Compose Foundation con mejoras específicas para Wear que permiten mejorar el rendimiento y el cumplimiento de los lineamientos de Wear OS. |
|
Se puede usar en lugar de |
|
Botones
Los botones en 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 EdgeButton a ScreenScaffold para que se transforme y cambie de forma con el desplazamiento. Consulta el siguiente código para verificar 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 ScreenScaffold componible 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 suministrar 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
AppScaffold { val navController = rememberSwipeDismissableNavController() SwipeDismissableNavHost( navController = navController, startDestination = "message_list" ) { composable("message_list") { MessageList(onMessageClick = { id -> navController.navigate("message_detail/$id") }) } composable("message_detail/{id}") { MessageDetail(id = it.arguments?.getString("id")!!) } } } } // Implementation of one of the screens in the navigation @Composable fun MessageDetail(id: String) { // .. Screen level content goes here val scrollState = rememberTransformingLazyColumnState() val padding = rememberResponsiveColumnPadding( first = ColumnItemType.BodyText ) ScreenScaffold( scrollState = scrollState, contentPadding = padding ) { scaffoldPaddingValues -> // Screen content goes here // ...
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 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 visualización y el ocultamiento de TimeText y HorizontalPageIndicator según si se está paginando el Pager. Esto lo determina el PagerState.
También hay un nuevo componente AnimatedPage, que anima una página dentro de un Pager con un efecto de escala y de velo según su posición.
AppScaffold { val pagerState = rememberPagerState(pageCount = { 10 }) val columnState = rememberTransformingLazyColumnState() val contentPadding = rememberResponsiveColumnPadding( first = ColumnItemType.ListHeader, last = ColumnItemType.BodyText, ) HorizontalPagerScaffold(pagerState = pagerState) { HorizontalPager( state = pagerState, ) { page -> AnimatedPage(pageIndex = page, pagerState = pagerState) { ScreenScaffold( scrollState = columnState, contentPadding = contentPadding ) { contentPadding -> TransformingLazyColumn( state = columnState, contentPadding = contentPadding ) { item { ListHeader( modifier = Modifier.fillMaxWidth() ) { Text(text = "Pager sample") } } item { if (page == 0) { Text(text = "Page #$page. Swipe right") } else{ Text(text = "Page #$page. Swipe left and right") } } } } } } } }
Por último, M3 introduce un VerticalPagerScaffold que sigue el mismo patrón que el 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 M2.5 y M3.
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 de marcador de posición
Modifier.placeholderShimmerque proporciona un efecto de brillo de marcador de posición que se ejecuta en un bucle de animación mientras se espera que se carguen los datos.
Consulta la siguiente tabla para ver los cambios adicionales en el componente Placeholder.
M2.5 |
M3 |
|---|---|
|
Se quitó |
|
Se quitó |
|
Se cambió el nombre a |
|
Se quitó |
|
Se quitó |
|
Se quitó |
|
Se quitó |
SwipeDismissableNavHost
SwipeDismissableNavHost forma parte de wear.compose.navigation. Cuando este componente se usa con M3, el MaterialTheme de M3 actualiza LocalSwipeToDismissBackgroundScrimColor y LocalSwipeToDismissContentScrimColor.
TransformingLazyColumn
TransformingLazyColumn forma parte de wear.compose.lazy.foundation y agrega compatibilidad con animaciones de cambio de forma y de ajuste de escala en los elementos de la lista durante el desplazamiento, lo que mejora la experiencia del usuario.
De manera similar a ScalingLazyColumn, proporciona rememberTransformingLazyColumnState() para crear un TransformingLazyColumnState que se recuerde 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 unTransformationSpec, puedes usarrememberTransformationSpec(), a menos que necesites más personalización.- Un
SurfaceTransformation
val columnState = rememberTransformingLazyColumnState() val contentPadding = rememberResponsiveColumnPadding( first = ColumnItemType.ListHeader, last = ColumnItemType.Button, ) val transformationSpec = rememberTransformationSpec() ScreenScaffold( scrollState = columnState, contentPadding = contentPadding ) { contentPadding -> TransformingLazyColumn( state = columnState, contentPadding = contentPadding ) { item { ListHeader( modifier = Modifier.fillMaxWidth().transformedHeight(this, transformationSpec), transformation = SurfaceTransformation(transformationSpec) ) { Text(text = "Header") } } // ... other items item { Button( modifier = Modifier.fillMaxWidth().transformedHeight(this, transformationSpec), transformation = SurfaceTransformation(transformationSpec), onClick = { /* ... */ }, icon = { Icon( imageVector = Icons.Default.Build, contentDescription = "build", ) }, ) { Text( text = "Build", maxLines = 1, overflow = TextOverflow.Ellipsis, ) } } } }
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.