Material Design 3 to kolejna ewolucja Material Design. Obejmuje zaktualizowane motywy, komponenty i funkcje personalizacji Material You, takie jak dynamiczne kolory. Jest to aktualizacja Material Design 2, która jest spójna z nowym stylem wizualnym i interfejsem systemu na Androidzie 12 i nowszym.
Ten przewodnik zawiera informacje o migracji z biblioteki Jetpack Compose Material (androidx.compose.material) do biblioteki Jetpack Compose Material 3 (androidx.compose.material3).
Podejścia
Ogólnie rzecz biorąc, nie należy długoterminowo używać w jednej aplikacji zarówno M2, jak i M3. Wynika to z faktu, że oba systemy projektowania i odpowiednie biblioteki znacznie się od siebie różnią pod względem projektów UX/UI i implementacji Compose.
Aplikacja może korzystać z systemu projektowania, np. utworzonego za pomocą Figmy. W takich przypadkach zdecydowanie zalecamy, aby Ty lub Twój zespół projektowy przenieśli go z M2 do M3 przed rozpoczęciem migracji do Compose. Nie ma sensu przenosić aplikacji do M3, jeśli jej projekt UX/UI jest oparty na M2.
Ponadto podejście do migracji powinno się różnić w zależności od rozmiaru, złożoności i projektu UX/UI aplikacji. Dzięki temu zminimalizujesz wpływ na bazę kodu. Migrację należy przeprowadzać etapami.
Kiedy przeprowadzić migrację
Migrację należy rozpocząć jak najszybciej. Warto jednak zastanowić się, czy Twoja aplikacja jest w stanie w pełni przejść z M2 na M3. Zanim zaczniesz, rozważ te scenariusze blokujące:
Scenariusz | Zalecane działania |
---|---|
Brak czynników blokujących | Rozpocznij migrację etapową |
Komponent z M2 nie jest jeszcze dostępny w M3. Więcej informacji znajdziesz w sekcji Komponenty i układy poniżej. | Rozpocznij migrację etapową |
Ty lub Twój zespół projektowy nie przenieśliście systemu projektowania aplikacji z M2 na M3. | Przenieś system projektowania z M2 na M3, a potem rozpocznij migrację etapową. |
Nawet jeśli dotyczą Cię powyższe scenariusze, przed wprowadzeniem i opublikowaniem aktualizacji aplikacji warto zastosować podejście etapowe. W takich przypadkach używasz modeli M2 i M3 równolegle i stopniowo wycofujesz model M2, przechodząc na model M3.
Podejście etapowe
Ogólne etapy migracji etapowej są następujące:
- Dodaj zależność M3 obok zależności M2.
- Dodaj wersje M3 motywów aplikacji obok wersji M2 motywów aplikacji.
- Przenieś poszczególne moduły, ekrany lub komponenty do M3 w zależności od rozmiaru i złożoności aplikacji (szczegółowe informacje znajdziesz w sekcjach poniżej).
- Po pełnej migracji usuń wersje M2 motywów aplikacji.
- Usuń zależność M2.
Zależności
M3 ma osobny pakiet i wersję niż M2:
M2
implementation "androidx.compose.material:material:$m2-version"
M3
implementation "androidx.compose.material3:material3:$m3-version"
Najnowsze wersje M3 znajdziesz na stronie z informacjami o wersjach Compose Material 3.
Zależności od innych materiałów poza głównymi bibliotekami M2 i M3 nie uległy zmianie. Używają one różnych pakietów i wersji M2 i M3, ale nie ma to wpływu na migrację. Można ich używać w M3 w takiej postaci:
Biblioteka | Pakiet i wersja |
---|---|
Tworzenie ikon Material | androidx.compose.material:material-icons-*:$m2-version |
Komponowanie efektu fali Material | androidx.compose.material:material-ripple:$m2-version |
Eksperymentalne interfejsy API
Niektóre interfejsy API M3 są uznawane za eksperymentalne. W takich przypadkach musisz wyrazić zgodę na poziomie funkcji lub pliku, używając adnotacji ExperimentalMaterial3Api
:
import androidx.compose.material3.ExperimentalMaterial3Api
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppComposable() {
// M3 composables
}
Motywy
W przypadku M2 i M3 funkcja kompozycyjna motywu ma nazwę MaterialTheme
, ale pakiety importu i parametry różnią się:
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
}
Kolor

System kolorów w M3 znacznie różni się od tego w M2. Liczba parametrów koloru wzrosła, mają one różne nazwy i inaczej mapują się na komponenty M3. W Compose dotyczy to klasy M2
Colors
, klasy M3 ColorScheme
i powiązanych funkcji:
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
}
Ze względu na znaczące różnice między systemami kolorów M2 i M3 nie ma rozsądnego mapowania parametrów Color
. Zamiast tego użyj narzędzia do tworzenia motywów Material, aby wygenerować schemat kolorów M3. Używaj kolorów M2 jako podstawowych kolorów źródłowych w narzędziu, które rozszerza je na palety tonalne używane przez schemat kolorów M3. Jako punkt wyjścia zalecamy te mapowania:
M2 | Kreator motywów Material Design |
---|---|
primary |
Podstawowy |
primaryVariant |
Secondary |
secondary |
Trzeciorzędny |
surface lub background |
Nie mam zdania |

Możesz skopiować wartości szesnastkowe kodów kolorów dla motywów jasnego i ciemnego z narzędzia i użyć ich do wdrożenia instancji M3 ColorScheme. Możesz też wyeksportować kod Compose za pomocą narzędzia Material Theme Builder.
isLight
W przeciwieństwie do klasy M2 Colors
klasa M3 ColorScheme
nie zawiera parametru isLight
. Zasadniczo staraj się modelować wszystko, co wymaga tych informacji, na poziomie motywu. Na przykład:
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
…
}
}
Więcej informacji znajdziesz w przewodniku po niestandardowych systemach projektowania w Compose.
Kolory dynamiczne
Nową funkcją M3 jest dynamiczny kolor. Zamiast używać niestandardowych kolorów, M3 ColorScheme
może korzystać z kolorów tapety urządzenia na Androidzie 12 i nowszym, używając tych funkcji:
Typografia

System typografii w M3 różni się od tego w M2. Liczba parametrów typografii jest mniej więcej taka sama, ale mają one inne nazwy i inaczej są mapowane na komponenty M3. W Compose dotyczy to klas M2
Typography
i M3 Typography
:
M2
import androidx.compose.material.Typography
val AppTypography = Typography(
// M2 TextStyle parameters
)
M3
import androidx.compose.material3.Typography
val AppTypography = Typography(
// M3 TextStyle parameters
)
Jako punkt wyjścia zalecamy te mapowania parametrów TextStyle
:
M2 | M3 |
---|---|
h1 |
displayLarge |
h2 |
displayMedium |
h3 |
displaySmall |
Nie dotyczy | headlineLarge |
h4 |
headlineMedium |
h5 |
headlineSmall |
h6 |
titleLarge |
subtitle1 |
titleMedium |
subtitle2 |
titleSmall |
body1 |
bodyLarge |
body2 |
bodyMedium |
caption |
bodySmall |
button |
labelLarge |
Nie dotyczy | labelMedium |
overline |
labelSmall |
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. W przypadku tworzenia wiadomości dotyczy to klas M2 Shapes
i M3 Shapes
:
M2
import androidx.compose.material.Shapes
val AppShapes = Shapes(
// M2 Shape parameters
)
M3
import androidx.compose.material3.Shapes
val AppShapes = Shapes(
// M3 Shape parameters
)
Jako punkt wyjścia zalecamy te mapowania parametrów Shape
:
M2 | M3 |
---|---|
Nie dotyczy | extraSmall |
small |
small |
medium |
medium |
large |
large |
Nie dotyczy | extraLarge |
Komponenty i układy
Większość komponentów i układów z M2 jest dostępna w M3. Brakuje jednak niektórych z nich, a pojawiają się nowe, których nie było w M2. Ponadto niektóre komponenty M3 mają więcej wariantów niż ich odpowiedniki w M2. Ogólnie rzecz biorąc, interfejsy M3 API są jak najbardziej podobne do swoich odpowiedników w M2.
Ze względu na zaktualizowane systemy kolorów, typografii i kształtów komponenty M3 są zwykle inaczej mapowane na nowe wartości motywu. Warto zapoznać się z katalogiem tokenów w kodzie źródłowym Compose Material 3, aby uzyskać informacje o tych mapowaniach.
Niektóre komponenty wymagają szczególnej uwagi, ale jako punkt wyjścia zalecamy te mapowania funkcji:
Brakujące interfejsy API:
M2 | M3 |
---|---|
androidx.compose.material.swipeable |
Jeszcze niedostępne |
Zastąpione interfejsy API:
M2 | M3 |
---|---|
androidx.compose.material.BackdropScaffold |
Brak odpowiednika M3, zamiast tego przeprowadź migrację do Scaffold lub BottomSheetScaffold |
androidx.compose.material.BottomDrawer |
Brak odpowiednika M3, zamiast tego przeprowadź migrację do ModalBottomSheet |
Interfejsy API, których nazwy zostały zmienione:
Wszystkie pozostałe interfejsy API:
Najnowsze komponenty i układy M3 znajdziesz w przeglądzie interfejsu Compose Material 3 API. Nowe i zaktualizowane interfejsy API znajdziesz na stronie z informacjami o wersjach.
Scaffold, snackbary i panel nawigacji

Platforma w M3 różni się od platformy w M2. W przypadku M2 i M3 główny układ kompozycyjny ma nazwę Scaffold
, ale pakiety importu i parametry są różne:
M2
import androidx.compose.material.Scaffold
Scaffold(
// M2 scaffold parameters
)
M3
import androidx.compose.material3.Scaffold
Scaffold(
// M3 scaffold parameters
)
Parametr backgroundColor
w M2 Scaffold
ma teraz nazwę containerColor
w M3 Scaffold
:
M2
import androidx.compose.material.Scaffold
Scaffold(
backgroundColor = …,
content = { … }
)
M3
import androidx.compose.material3.Scaffold
Scaffold(
containerColor = …,
content = { … }
)
Klasa M2 ScaffoldState
nie istnieje już w M3, ponieważ zawiera parametr drawerState
, który nie jest już potrzebny. Aby wyświetlać paski z Scaffold
w Materialu 3, użyj 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(…)
}
}
)
Wszystkie parametry drawer*
z Scaffold
M2 zostały usunięte z Scaffold
M3. Obejmują one parametry takie jak drawerShape
i drawerContent
. Aby wyświetlić panel z elementem Scaffold
w stylu M3, użyj funkcji kompozycyjnej panelu nawigacji, np. 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()
}
}
)
}
)
Górny pasek aplikacji

Górne paski aplikacji w M3 różnią się od tych w M2. W przypadku M2 i M3 główny komponent kompozycyjny górnego paska aplikacji ma nazwę TopAppBar
, ale pakiety importu i parametry różnią się:
M2
import androidx.compose.material.TopAppBar
TopAppBar(…)
M3
import androidx.compose.material3.TopAppBar
TopAppBar(…)
Jeśli wcześniej wyśrodkowywałeś(-aś) treści w przypadku M2 TopAppBar
, rozważ użycie M3 CenterAlignedTopAppBar
. Warto też znać MediumTopAppBar
i LargeTopAppBar
.
Górne paski aplikacji M3 zawierają nowy parametr scrollBehavior
, który zapewnia różne funkcje podczas przewijania klasy TopAppBarScrollBehavior
, np. zmianę wysokości. Działa to w połączeniu z przewijaniem treści za pomocą Modifer.nestedScroll
. W M2 TopAppBar
było to możliwe dzięki ręcznej zmianie parametru 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 { … }
}
)
Dolna nawigacja / pasek nawigacyjny

Dolna nawigacja w M2 została w M3 zmieniona na pasek nawigacyjny. W module M2 znajdują się funkcje kompozycyjne BottomNavigation
i BottomNavigationItem
, a w module M3 – funkcje kompozycyjne NavigationBar
i 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(…)
}
Przyciski, przyciski z ikonami i FAB

Przyciski, przyciski z ikonami i pływające przyciski polecenia w M3 różnią się od tych w M2. M3 zawiera wszystkie komponenty przycisku 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(…)
M3 zawiera też nowe warianty przycisków. Znajdziesz je w omówieniu interfejsu Compose Material 3 API.
Przełącz

Przełącznik w M3 różni się od tego w M2. W przypadku M2 i M3 komponent przełącznika ma nazwę Switch
, ale pakiety importu różnią się:
M2
import androidx.compose.material.Switch
Switch(…)
M3
import androidx.compose.material3.Switch
Switch(…)
Powierzchnie i wysokość

Systemy powierzchni i wysokości w M3 różnią się od tych w M2. W M3 są 2 rodzaje wzniesień:
- Wysokość cienia (rzuca cień, tak samo jak M2)
- Podniesienie tonalne (nakładanie koloru, nowość w M3)
W przypadku tworzenia wiadomości dotyczy to funkcji M2 Surface
i M3 Surface
:
M2
import androidx.compose.material.Surface
Surface(
elevation = …
) { … }
M3
import androidx.compose.material3.Surface
Surface(
shadowElevation = …,
tonalElevation = …
) { … }
W przypadku obu wartości shadowElevation
i tonalElevation
w M3 możesz użyć wartości elevation
Dp
w M2, w zależności od preferencji dotyczących projektu UX/UI.
Surface
to kompozycja bazowa większości komponentów, więc kompozycje komponentów mogą też udostępniać parametry wysokości, które musisz przenieść w ten sam sposób.
W M3 tonalne podniesienie zastępuje koncepcję nakładek podniesienia w ciemnych motywach M2 . W związku z tym w M3 nie ma funkcji ElevationOverlay
i LocalElevationOverlay
, a funkcja LocalAbsoluteElevation
w M2 została zmieniona na LocalAbsoluteTonalElevation
w M3.
Podkreślenie i przezroczystość treści

Nacisk w M3 jest znacznie inny niż w M2. W M2 nacisk polegał na używaniu kolorów on z określonymi wartościami alfa, aby odróżnić treści takie jak tekst i ikony. W M3 dostępne są teraz 2 różne podejścia:
- Używaj kolorów on wraz z ich wariantami z rozszerzonego systemu kolorów M3.
- Używanie różnych grubości czcionki w tekście.
W związku z tym w M3 nie ma znaków ContentAlpha
i LocalContentAlpha
, więc trzeba je zastąpić.
Na początek zalecamy te skróty:
M2 | M3 |
---|---|
onSurface w aplikacji ContentAlpha.high |
onSurface – ogólnie FontWeight.Medium – FontWeight.Black w przypadku tekstu. |
onSurface w aplikacji ContentAlpha.medium |
onSurfaceVariant – ogólnie FontWeight.Thin – FontWeight.Normal w przypadku tekstu; |
onSurface w aplikacji ContentAlpha.disabled |
onSurface.copy(alpha = 0.38f) |
Oto przykład wyróżnienia ikony w M2 i 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(…)
}
Oto przykłady wyróżnienia tekstu w przypadku poziomów M2 i 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
)
}
Tła i kontenery
Tła w M2 są nazwanymi kontenerami w M3. Ogólnie rzecz biorąc, możesz zastąpić parametry background*
w M2 parametrami container*
w M3, używając tych samych wartości.
Na przykład:
M2
Badge(
backgroundColor = MaterialTheme.colors.primary
) { … }
M3
Badge(
containerColor = MaterialTheme.colorScheme.primary
) { … }
Przydatne linki
Więcej informacji o migracji z M2 do M3 w Compose znajdziesz w tych dodatkowych materiałach.
Dokumenty
Przykładowe aplikacje
- Przykładowa aplikacja Reply M3
- Migracja aplikacji przykładowej Jetchat z M2 na M3
- Migracja aplikacji przykładowej Jetnews z M2 na M3
- Now in Android M3 hero app :core-designsystem module
Filmy
Dokumentacja API i kod źródłowy
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy JavaScript jest wyłączony.
- Material Design 2 w Compose
- Material Design 3 w Compose
- Niestandardowe systemy projektowania w Compose