Material 3 Expressive to kolejna ewolucja Material Design. Obejmuje ona zaktualizowane motywy, komponenty i funkcje personalizacji, takie jak dynamiczny kolor.
Ten przewodnik zawiera informacje o migracji z biblioteki Jetpack Wear Compose Material 2.5 (androidx.wear.compose) do biblioteki Jetpack Wear Compose Material 3 (androidx.wear.compose.material3) w przypadku aplikacji.
Podejścia
Aby przenieść kod aplikacji z M2.5 do M3, postępuj zgodnie z instrukcjami opisanymi w przewodniku po migracji do biblioteki Compose Material na telefonie, a w szczególności:
- Nie należy długoterminowo używać w jednej aplikacji zarówno M2.5, jak i M3.
- Zastosuj podejście etapowe.
Zależności
M3 ma osobny pakiet i wersję niż M2.5:
M2,5
implementation("androidx.wear.compose:compose-material:1.4.0")
M3
implementation("androidx.wear.compose:compose-material3:1.6.0-alpha04")
Najnowsze wersje M3 znajdziesz na stronie Wear Compose Material 3.
W bibliotece Wear Compose Foundation w wersji 1.6.0-alpha04 wprowadzono nowe komponenty, które są przeznaczone do współpracy z komponentami Material 3.
Podobnie SwipeDismissableNavHost z biblioteki Wear Compose Navigation ma zaktualizowaną animację, gdy jest uruchamiana na Wear OS 6 (API na poziomie 36) lub nowszym. Podczas aktualizacji do wersji Wear Compose Material 3 zalecamy też zaktualizowanie bibliotek Wear Compose Foundation i Navigation:
implementation("androidx.wear.compose:compose-foundation:1.6.0-alpha04")
implementation("androidx.wear.compose:compose-navigation:1.6.0-alpha04")
Motyw
W przypadku M2.5 i M3 funkcja kompozycyjna motywu ma nazwę MaterialTheme, ale pakiety importu i parametry różnią się. W M3 parametr Colors został zmieniony na ColorScheme, a do implementacji przejść wprowadzono parametr MotionScheme.
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
)
Kolor
System kolorów w M3 znacznie różni się od tego w M2.5. Liczba parametrów koloru wzrosła, mają one inne nazwy i inaczej mapują się na komponenty M3. W przypadku funkcji Compose dotyczy to klas M2.5 Colors, M3 ColorScheme i powiązanych funkcji:
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
)
W tej tabeli opisano najważniejsze różnice między M2.5 i M3:
| M2,5 | M3 | 
|---|---|
| 
 | została zmieniona na  | 
| 13 kolorów | 28 kolorów | 
| Nie dotyczy | nowe dynamiczne motywy kolorystyczne, | 
| Nie dotyczy | nowe kolory trzeciorzędowe, które pozwolą Ci wyrazić więcej emocji; | 
Dynamiczne motywy kolorystyczne
Nową funkcją w M3 jest dynamiczne dopasowywanie kolorów. Jeśli użytkownicy zmienią kolory tarczy zegarka, kolory w interfejsie zmienią się tak, aby do nich pasować.
Użyj funkcji dynamicColorScheme, aby wdrożyć dynamiczny schemat kolorów, i podaj defaultColorScheme jako rezerwę na wypadek, gdyby dynamiczny schemat kolorów był niedostępny.
@Composable
fun myApp() {
  val myColorScheme = myBrandColors()
  val dynamicColorScheme = dynamicColorScheme(LocalContext.current)
  MaterialTheme(colorScheme = dynamicColorScheme ?: myBrandColors) {...}
}
Typografia
System typografii w M3 różni się od tego w M2 i obejmuje te funkcje:
- 9 nowych stylów tekstu
- czcionki elastyczne, które umożliwiają dostosowywanie skal typograficznych do różnych grubości, szerokości i zaokrągleń;
- AnimatedText, który używa czcionek elastycznych;
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
)
Czcionki Flex
Czcionki elastyczne umożliwiają projektantom określanie szerokości i grubości znaków dla konkretnych rozmiarów.
Style tekstu
W M3 dostępne są te TextStyles: Są one domyślnie używane przez różne komponenty M3.
| Typografia | TextStyle | 
|---|---|
| Wyświetlacz | displayLarge, displayMedium, displaySmall | 
| Tytuł | titleLarge, titleMedium, titleSmall | 
| Etykieta | labelLarge, labelMedium, labelSmall | 
| Treść | bodyLarge, bodyMedium, bodySmall, bodyExtraSmall | 
| Cyfry | numeralExtraLarge, numeralLarge, numeralMedium, numeralSmall, numeralExtraSmall | 
| Łuk | arcLarge, arcMedium, arcSmall | 
Kształt
System kształtów w M3 różni się od tego w M2. Liczba parametrów kształtu wzrosła, mają one inne nazwy i inaczej są mapowane na komponenty M3. Dostępne są te rozmiary kształtów:
- Bardzo mały
- Mały
- średni,
- Duży
- Bardzo duży
W Compose dotyczy to klas M2 Shapes i M3 Shapes:
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
)
Jako punktu wyjścia użyj mapowania parametrów kształtów z artykułu Migracja z Material 2 do Material 3 w Compose.
Przekształcanie kształtu
M3 wprowadza zmianę kształtu: kształty zmieniają się teraz w odpowiedzi na interakcje.
Zachowanie Zmiana kształtu jest dostępne jako odmiana kilku okrągłych przycisków. Poniżej znajdziesz listę przycisków, które obsługują zmianę kształtu:
| Przyciski | Funkcja przekształcania kształtu | 
|---|---|
| 
 | IconButtonDefaults.animatedShape() animuje przycisk ikony po naciśnięciu. | 
| 
 | IconToggleButtonDefaults.animatedShape() animuje przycisk przełączania ikony po naciśnięciu i IconToggleButtonDefaults.variantAnimatedShapes() animuje przycisk przełączania ikony po naciśnięciu i zaznaczeniu/odznaczeniu. | 
| 
 | TextButtonDefaults.animatedShape() animuje przycisk tekstowy po naciśnięciu. | 
| 
 | TextToggleButtonDefaults.animatedShapes() animuje przełącznik tekstowy po naciśnięciu, a TextToggleButtonDefaults.variantAnimatedShapes() animuje przełącznik tekstowy po naciśnięciu i zaznaczeniu/odznaczeniu. | 
Komponenty i układ
Większość komponentów i układów z M2.5 jest dostępna w M3. Niektóre komponenty i układy M3 nie występowały jednak w M2.5. Ponadto niektóre komponenty M3 mają więcej wariantów niż ich odpowiedniki w M2.5.
Niektóre komponenty wymagają szczególnej uwagi, ale jako punkt wyjścia zalecamy te mapowania funkcji:
Oto pełna lista wszystkich komponentów Material 3:
| Material 3 | Odpowiednik komponentu Material 2.5 (jeśli nie jest nowością w M3) | 
|---|---|
| Nowość | |
| Nowość | |
| android.wear.compose.material.Scaffold (z androidx.wear.compose.material3.ScreenScaffold) | |
| Nowość | |
| androidx.wear.compose.material.ToggleChip z elementem sterującym przełączania w postaci pola wyboru | |
| androidx.wear.compose.material.Chip (tylko wtedy, gdy nie jest wymagane tło) | |
| Nowość | |
| Nowość | |
| Nowość | |
| androidx.wear.compose.material.Chip, gdy wymagane jest tło przycisku tonalnego. | |
| Nowość | |
| Nowość | |
| Nowość | |
| Nowość | |
| Nowość | |
| androidx.wear.compose.material.ToggleChip z elementem sterującym w postaci opcji | |
| android.wear.compose.material.Scaffold (z androidx.wear.compose.material3.AppScaffold) | |
| androidx.wear.compose.material3.SegmentedCircularProgressIndicator | Nowość | 
| androidx.wear.compose.material.SwipeToRevealCard i androidx.wear.compose.material.SwipeToRevealChip | |
| androidx.wear.compose.material.ToggleChip z przełącznikiem | |
| Nowość | 
Na koniec lista niektórych komponentów z biblioteki Wear Compose Foundation, która została wprowadzona w wersji 1.6.0-alpha04:
| Wear Compose Foundation 1.6.0-alpha04 | |
|---|---|
| Służy do dodawania adnotacji do funkcji kompozycyjnych w aplikacji, aby śledzić aktywną część kompozycji i koordynować fokus. | |
| Przewijany w poziomie pager oparty na komponentach Compose Foundation z ulepszeniami dostosowanymi do Wear, które zwiększają wydajność i zgodność z wytycznymi Wear OS. | |
| Przewijany pionowo pager oparty na komponentach Compose Foundation z ulepszeniami dostosowanymi do Wear, które zwiększają wydajność i zgodność z wytycznymi Wear OS. | |
| Można go używać zamiast  | |
Przyciski
Przyciski w M3 różnią się od przycisków w M2.5. Element M2.5 Chip został zastąpiony elementem Button. Implementacja Button zapewnia domyślne wartości parametrów Text
maxLines i textAlign. Te wartości domyślne można zastąpić w elemencie 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 zawiera też nowe warianty przycisków. Zapoznaj się z nimi w omówieniu interfejsu Compose Material 3 API.
W M3 wprowadziliśmy nowy przycisk: EdgeButton. EdgeButton jest dostępny w 4 rozmiarach: bardzo małym, małym, średnim i dużym. EdgeButton
implementacja podaje domyślną wartość parametru maxLines w zależności od rozmiaru,
którą można dostosować.
Jeśli używasz TransformingLazyColumn i ScalingLazyColumn, przekaż EdgeButton do ScreenScaffold, aby zmieniał kształt podczas przewijania. Zapoznaj się z poniższym kodem, aby sprawdzić, jak używać funkcji EdgeButton z ScreenScaffold i 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
Scaffold w M3 różni się od tego w M2.5. W M3 komponent AppScaffold i nowy komponent ScreenScaffold zastąpiły komponent Scaffold. AppScaffold i ScreenScaffold określają strukturę ekranu i koordynują przejścia komponentów ScrollIndicator i TimeText.
AppScaffold umożliwia pozostawienie widocznych statycznych elementów ekranu, takich jak TimeText, podczas przejść w aplikacji, np. podczas zamykania aplikacji gestem. Zapewnia miejsce na główną zawartość aplikacji, która zwykle jest dostarczana przez komponent nawigacyjny, taki jak SwipeDismissableNavHost
Deklarujesz 1 AppScaffold dla aktywności i używasz ScreenScaffold dla każdego ekranu.
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 // ...
Jeśli używasz HorizontalPager z HorizontalPagerIndicator, możesz przejść na HorizontalPagerScaffold. Element HorizontalPagerScaffold jest umieszczony w AppScaffold. AppScaffold i HorizontalPagerScaffold określają strukturę komponentu Pager i koordynują przejścia komponentów HorizontalPageIndicator i TimeText.
HorizontalPagerScaffold domyślnie wyświetla HorizontalPageIndicator na środku ekranu i koordynuje wyświetlanie i ukrywanie TimeText i HorizontalPageIndicator w zależności od tego, czy Pager jest stronicowany. Określa to parametr PagerState.
Jest też nowy komponent AnimatedPage, który animuje stronę w komponencie Pager za pomocą efektu skalowania i przesłony w zależności od jej pozycji.
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") } } } } } } } }
Na koniec M3 wprowadza VerticalPagerScaffold, które ma taki sam wzór jak 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 {
        …
   }
}
Obiekt zastępczy
Między wersjami M2.5 i M3 interfejsu API występują pewne różnice.
Placeholder.PlaceholderDefaults udostępnia teraz 2 modyfikatory:
- Modifier.placeholder, który jest rysowany zamiast treści, które nie zostały jeszcze wczytane.
- Efekt migotania elementu zastępczego Modifier.placeholderShimmer, który zapewnia efekt migotania elementu zastępczego działający w pętli animacji podczas oczekiwania na załadowanie danych.
Dodatkowe zmiany w komponencie Placeholder znajdziesz w tabeli poniżej.
| M2,5 | M3 | 
|---|---|
| 
 | został usunięty. | 
| 
 | został usunięty. | 
| 
 | Zmieniono nazwę na  | 
| 
 | został usunięty. | 
| 
 | został usunięty. | 
| 
 | został usunięty. | 
| 
 | został usunięty. | 
SwipeDismissableNavHost
SwipeDismissableNavHost jest częścią usługi wear.compose.navigation. Gdy ten komponent jest używany z M3, M3 MaterialTheme aktualizuje LocalSwipeToDismissBackgroundScrimColor i LocalSwipeToDismissContentScrimColor.
TransformingLazyColumn
TransformingLazyColumn jest częścią wear.compose.lazy.foundation i dodaje obsługę skalowania i przekształcania animacji elementów listy podczas przewijania, co zwiększa wygodę użytkownika.
Podobnie jak w przypadku ScalingLazyColumn, zapewnia rememberTransformingLazyColumnState(), aby utworzyć TransformingLazyColumnState, który jest zapamiętywany w różnych kompozycjach.
Aby dodać animacje skalowania i przekształcania, dodaj do każdego elementu listy te informacje:
- Modifier.transformedHeight, który umożliwia obliczanie przekształconej wysokości elementów za pomocą- TransformationSpec. Możesz użyć- rememberTransformationSpec(), chyba że potrzebujesz dalszego dostosowania.
- 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, ) } } } }
Przydatne linki
Więcej informacji o migracji z M2.5 do M3 w Compose znajdziesz w tych materiałach.
