Migracja z wersji Material 2.5 na Material 3 w Compose na Wear OS

Material 3 Expressive to kolejna ewolucja Material Design. Obejmuje ona zaktualizowane motywy, komponenty i funkcje personalizacji, takie jak dynamiczny kolor.

Ten przewodnik skupia się na 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:

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")

Najnowsze wersje M3 znajdziesz na stronie Wear Compose Material 3.

W bibliotece Wear Compose Foundation w wersji 1.6.0 wprowadziliśmy 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")
implementation("androidx.wear.compose:compose-navigation:1.6.0")

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 = ColorScheme(),
        typography = Typography(),
        shapes = Shapes(),
        motionScheme = MotionScheme.standard(),
        content = { /*content here*/ }
    )

Kolor

System kolorów w M3 znacznie różni się od tego w M2.5. Liczba parametrów koloru wzrosła, mają one różne nazwy i inaczej mapują się na komponenty M3. W przypadku 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
Color Zmieniono nazwę na ColorScheme
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

Dynamiczne motywy kolorystyczne

Nową funkcją M3 jest dynamiczne kolorowanie. 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 dynamicColorScheme = dynamicColorScheme(LocalContext.current)
    MaterialTheme(colorScheme = dynamicColorScheme ?: myBrandColors) {}
}

internal val myBrandColors: ColorScheme = ColorScheme( /* Specify colors here */)

Typografia

System typografii w M3 różni się od tego w M2.5 i obejmuje te funkcje:

  • 9 nowych stylów tekstu
  • czcionki elastyczne, które umożliwiają dostosowywanie skal typów do różnych grubości, szerokości i zaokrągleń;
  • AnimatedText, który używa elastycznych czcionek;

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 elastyczne

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.5. 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 punkt początkowy użyj mapowania parametrów kształtów z artykułu Migracja z Material 2 na Material 3 w Compose.

Przekształcanie kształtu

W M3 wprowadziliśmy zmianę kształtu: kształty zmieniają się teraz w odpowiedzi na interakcje.

Funkcja zmiany kształtu jest dostępna w przypadku 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
IconButton IconButtonDefaults.animatedShape animuje przycisk ikony po naciśnięciu.
IconToggleButton IconToggleButtonDefaults.animatedShape animuje przycisk przełączania ikony po naciśnięciu, a
IconToggleButtonDefaults.variantAnimatedShapes animuje przycisk przełączania ikony po naciśnięciu i zaznaczeniu/odznaczeniu.
TextButton TextButtonDefaults.animatedShape animuje przycisk tekstowy po naciśnięciu.
TextToggleButton TextToggleButtonDefaults.animatedShapes animuje przełącznik tekstowy po naciśnięciu, a TextToggleButtonDefaults.variantAnimatedShapes animuje przełącznik tekstowy po naciśnięciu oraz zaznaczeniu lub 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 odmian niż ich odpowiedniki w M2.5.

Niektóre komponenty wymagają szczególnej uwagi, ale jako punkt początkowy zalecamy te mapowania funkcji:

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 lub 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 Brak odpowiednika M3, przenieś do androidx.wear.compose.material3.CheckboxButton lub androidx.wear.compose.material3.SplitCheckboxButton
androidx.wear.compose.material.Chip androidx.wear.compose.material3.Button lub
androidx.wear.compose.material3.OutlinedButton lub
androidx.wear.compose.material3.FilledTonalButton lub
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() Został usunięty, ponieważ nie jest używany przez Text ani Icon w Material 3.
androidx.wear.compose.material.PositionIndicator androidx.wear.compose.material3.ScrollIndicator
androidx.wear.compose.material.RadioButton Brak odpowiednika w M3. Zmigruj do androidx.wear.compose.material3.RadioButton lub 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.AppScaffoldandroidx.wear.compose.material3.ScreenScaffold
androidx.wear.compose.material.SplitToggleChip Brak odpowiednika w M3, migracja do androidx.wear.compose.material3.SplitCheckboxButton, androidx.wear.compose.material3.SplitSwitchButton lub androidx.wear.compose.material3.SplitRadioButton
androidx.wear.compose.material.Switch Brak odpowiednika w M3. Przejdź na androidx.wear.compose.material3.SwitchButton lub androidx.wear.compose.material3.SplitSwitchButton.
androidx.wear.compose.material.ToggleButton androidx.wear.compose.material3.IconToggleButton lub androidx.wear.compose.material3.TextToggleButton
androidx.wear.compose.material.ToggleChip androidx.wear.compose.material3.CheckboxButton lub
androidx.wear.compose.material3.RadioButton lub
androidx.wear.compose.material3.SwitchButton
androidx.wear.compose.material.Vignette Usunięto, ponieważ nie jest to element systemu projektowania Material 3 Expressive na Wear OS

Oto pełna lista wszystkich komponentów Material 3:

Material 3 Odpowiednik komponentu Material 2.5 (jeśli nie jest nowością w M3)
androidx.wear.compose.material3.AlertDialog androidx.wear.compose.material.dialog.Alert
androidx.wear.compose.material3.AnimatedPage Nowość
androidx.wear.compose.material3.AnimatedText Nowość
androidx.wear.compose.material3.AppScaffold android.wear.compose.material.Scaffold (z androidx.wear.compose.material3.ScreenScaffold)
androidx.wear.compose.material3.Button androidx.wear.compose.material.Chip
androidx.wear.compose.material3.ButtonGroup Nowość
androidx.wear.compose.material3.Card androidx.wear.compose.material.Card
androidx.wear.compose.material3.CheckboxButton androidx.wear.compose.material.ToggleChip z elementem sterującym przełączania w postaci pola wyboru
androidx.wear.compose.material3.ChildButton androidx.wear.compose.material.Chip (tylko wtedy, gdy nie jest wymagane tło)
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 Nowość
androidx.wear.compose.material3.Dialog androidx.wear.compose.material.dialog.Dialog
androidx.wear.compose.material3.EdgeButton Nowość
androidx.wear.compose.material3.FadingExpandingLabel Nowość
androidx.wear.compose.material3.FilledTonalButton androidx.wear.compose.material.Chip, gdy wymagane jest tło przycisku tonalnego.
androidx.wear.compose.material3.HorizontalPageIndicator androidx.wear.compose.material.HorizontalPageIndicator
androidx.wear.compose.material3.HorizontalPagerScaffold Nowość
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 Nowość
androidx.wear.compose.material3.LinearProgressIndicator Nowość
androidx.wear.compose.material3.ListHeader androidx.wear.compose.material.ListHeader
androidx.wear.compose.material3.ListSubHeader Nowość
androidx.wear.compose.material3.MaterialTheme androidx.wear.compose.material.MaterialTheme
androidx.wear.compose.material3.OpenOnPhoneDialog Nowość
androidx.wear.compose.material3.Picker androidx.wear.compose.material.Picker
androidx.wear.compose.material3.PickerGroup androidx.wear.compose.material.PickerGroup
androidx.wear.compose.material3.RadioButton androidx.wear.compose.material.ToggleChip z elementem sterującym w postaci opcji
androidx.wear.compose.material3.ScreenScaffold android.wear.compose.material.Scaffold (z 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 Nowość
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.SwipeToRevealCardandroidx.wear.compose.material.SwipeToRevealChip
androidx.wear.compose.material3.SwitchButton androidx.wear.compose.material.ToggleChip z przełącznikiem
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 Nowość

Na koniec lista niektórych komponentów z biblioteki Wear Compose Foundation:

Wear Compose Foundation 1.6.0
androidx.wear.compose.foundation.hierarchicalFocusGroup Służy do dodawania adnotacji do funkcji kompozycyjnych w aplikacji, aby śledzić aktywną część kompozycji i koordynować fokus.
androidx.wear.compose.foundation.pager.HorizontalPager 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.
androidx.wear.compose.foundation.pager.VerticalPager Przewijany pionowo pager oparty na komponentach Compose Foundation z ulepszeniami dostosowanymi do Wear, które zwiększają wydajność i zgodność z wytycznymi Wear OS.
androidx.wear.compose.foundation.lazy.TransformingLazyColumn Można go używać zamiast ScalingLazyColumn, aby dodać do każdego elementu efekty przekształcenia podczas przewijania.

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 maxLinestextAlign. 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

//M3 Buttons
Button(onClick = { }){}
CompactButton(onClick = { }){}
IconButton(onClick = { }){}
TextButton(onClick = { }){}

M3 zawiera też nowe warianty przycisków. Zapoznaj się z nimi w omówieniu dokumentacji API Compose Material 3.

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 lub ScalingLazyColumn, przekaż EdgeButton do ScreenScaffold, aby zmieniał kształt podczas przewijania, zamiast dodawać EdgeButton jako ostatni element listy. Zapoznaj się z poniższym kodem, aby sprawdzić, jak używać funkcji EdgeButton z usługami ScreenScaffoldTransformingLazyColumn.

val state = rememberTransformingLazyColumnState()
ScreenScaffold(
    scrollState = state,
    contentPadding =
        rememberResponsiveColumnPadding(
            first = ColumnItemType.ListHeader
        ),
    edgeButton = {
        EdgeButton(
            onClick = { }
        ) {
            Text(stringResource(R.string.show))
        }
    }
){ contentPadding ->
    TransformingLazyColumn(state = state, contentPadding = contentPadding,){
        // additional code here
    }
}

Scaffold

Scaffold w M3 różni się od M2.5. W M3 komponent AppScaffold i nowy komponent ScreenScaffold zastąpiły komponent Scaffold. AppScaffoldScreenScaffold określają strukturę ekranu i koordynują przejścia komponentów ScrollIndicatorTimeText.

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 Activity i używasz ScreenScaffold dla każdego ekranu. AppScaffold dodaje do ekranów domyślny TimeTextkomponent. Możesz ją zastąpić, jeśli chcesz ją dostosować, używając parametru timeText.

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 HorizontalPagerHorizontalPagerIndicator, możesz przejść na HorizontalPagerScaffold. Element HorizontalPagerScaffold jest umieszczony w AppScaffold. AppScaffoldHorizontalPagerScaffold określają strukturę komponentu Pager i koordynują przejścia komponentów HorizontalPageIndicatorTimeText.

HorizontalPagerScaffold domyślnie wyświetla HorizontalPageIndicator na środku ekranu i koordynuje wyświetlanie i ukrywanie TimeTextHorizontalPageIndicator w zależności od tego, czy Pager jest stronicowany. Określa to PagerState.

Jest też nowy komponent AnimatedPage, który animuje stronę w komponencie Pager za pomocą efektu skalowania i przyciemniania 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")
                            }
                        }
                    }
                }

            }
        }
    }
}

W końcu M3 wprowadza VerticalPagerScaffold, które ma taki sam wzór jak HorizontalPagerScaffold:

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 połysku elementu zastępczego Modifier.placeholderShimmer, który zapewnia efekt połysku 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
PlaceholderState.startPlaceholderAnimation został usunięty.
PlaceholderState.placeholderProgression został usunięty.
PlaceholderState.isShowContent Zmieniono nazwę na !PlaceholderState.isVisible
PlaceholderState.isWipeOff został usunięty.
PlaceholderDefaults.painterWithPlaceholderOverlayBackgroundBrush został usunięty.
PlaceholderDefaults.placeholderBackgroundBrush został usunięty.
PlaceholderDefaults.placeholderChipColors został usunięty.

SwipeDismissableNavHost

SwipeDismissableNavHost jest częścią usługi wear.compose.navigation. Gdy ten komponent jest używany z M3, M3 MaterialTheme aktualizuje LocalSwipeToDismissBackgroundScrimColorLocalSwipeToDismissContentScrimColor.

TransformingLazyColumn

TransformingLazyColumn jest częścią wear.compose.lazy.foundation i dodaje obsługę animacji skalowania i przekształcania elementów listy podczas przewijania, co zwiększa komfort użytkowania. Zdecydowanie zalecamy migrację aplikacji z ScalingLazyColumn do TransformingLazyColumn.

Podobnie jak ScalingLazyColumn, udostępnia rememberTransformingLazyColumnState() do tworzenia TransformingLazyColumnState, który jest zapamiętywany w różnych kompozycjach.

Aby dodać animacje skalowania i przekształcania, dodaj do każdego elementu listy te elementy:

  • Modifier.transformedHeight, która umożliwia obliczanie przekształconej wysokości elementów za pomocą TransformationSpec. Możesz użyć rememberTransformationSpec(), chyba że potrzebujesz dalszej personalizacji.
  • SurfaceTransformation

Aby sprawdzić, czy dopełnienie u góry i u dołu listy jest prawidłowe, użyj modyfikatora minimumVerticalContentPadding.

val columnState = rememberTransformingLazyColumnState()
val transformationSpec = rememberTransformationSpec()
ScreenScaffold(
    scrollState = columnState
) { contentPadding ->
    TransformingLazyColumn(
        state = columnState,
        contentPadding = contentPadding
    ) {
        item {
            ListHeader(
                modifier = Modifier
                    .fillMaxWidth()
                    .transformedHeight(this, transformationSpec)
                    .minimumVerticalContentPadding(ListHeaderDefaults.minimumTopListContentPadding),
                transformation = SurfaceTransformation(transformationSpec)
            ) {
                Text(text = "Header")
            }
        }
        // ... other items
        item {
            Button(
                modifier = Modifier
                    .fillMaxWidth()
                    .transformedHeight(this, transformationSpec)
                    .minimumVerticalContentPadding(ButtonDefaults.minimumVerticalListContentPadding),
                transformation = SurfaceTransformation(transformationSpec),
                onClick = { /* ... */ },
                icon = {
                    Icon(
                        imageVector = Icons.Default.Build,
                        contentDescription = "build",
                    )
                },
            ) {
                Text(
                    text = "Build",
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis,
                )
            }
        }
    }
}

Więcej informacji o migracji z M2.5 do M3 w Compose znajdziesz w tych materiałach.

Próbki

Dokumentacja API i kod źródłowy

Projektowanie