Jetpack Compose oferuje implementację Material You i Material 3 Expressive, czyli kolejnej wersji Material Design. M3 Expressive to rozszerzenie Material Design 3, które obejmuje m.in. oparte na badaniach aktualizacje dotyczące motywów, komponentów, animacji, typografii i innych elementów. Wszystko po to, aby pomóc Ci tworzyć atrakcyjne i pożądane produkty, które spodobają się użytkownikom. Obsługuje też funkcje personalizacji Material You, takie jak dynamiczne kolory. M3 Expressive uzupełnia styl wizualny i interfejs systemu Androida 16.
Poniżej pokazujemy implementację Material Design 3 na przykładzie próbnej aplikacji Reply. Przykład odpowiedzi jest w pełni oparty na Material Design 3.

Zależność
Aby zacząć korzystać z Material 3 w aplikacji Compose, dodaj zależność Compose Material 3 do plików build.gradle
:
implementation "androidx.compose.material3:material3:$material3_version"
Po dodaniu zależności możesz zacząć dodawać do aplikacji systemy Material Design, w tym kolory, typografię i kształty.
Eksperymentalne interfejsy API
Niektóre interfejsy M3 są uważane za eksperymentalne. W takich przypadkach musisz wyrazić zgodę na poziomie funkcji lub pliku, używając adnotacji ExperimentalMaterial3Api
:
// import androidx.compose.material3.ExperimentalMaterial3Api @Composable fun AppComposable() { // M3 composables }
Motyw Material
Motyw M3 zawiera te podsystemy: schemat kolorów, typografia i kształty. Gdy dostosujesz te wartości, zmiany zostaną automatycznie uwzględnione w komponentach M3, których używasz do tworzenia aplikacji.

Jetpack Compose wdraża te koncepcje za pomocą komponentu M3 MaterialTheme
:
MaterialTheme( colorScheme = /* ... typography = /* ... shapes = /* ... ) { // M3 app content }
Aby stworzyć motyw dla treści aplikacji, określ schemat kolorów, typografię i kształty odpowiednie dla Twojej aplikacji.
Schemat kolorów
Podstawą schematu kolorów jest zestaw 5 kluczowych kolorów. Każdy z tych kolorów odnosi się do palety 13 tonów, które są używane przez komponenty Material 3. Oto na przykład schemat kolorów dla jasnego motywu w przypadku elementu Odpowiedź:

Dowiedz się więcej o schemacie kolorów i rolach kolorów.
Generowanie schematów kolorów
Możesz utworzyć niestandardowy ColorScheme
ręcznie, ale często łatwiej jest wygenerować go, używając kolorów źródłowych Twojej marki. Umożliwia to narzędzie Material Theme Builder, które pozwala też opcjonalnie wyeksportować kod stylów Compose. Wygenerowane zostaną te pliki:
Color.kt
zawiera kolory motywu ze wszystkimi zdefiniowanymi rolami w przypadku zarówno jasnego, jak i ciemnego motywu.
val md_theme_light_primary = Color(0xFF476810) val md_theme_light_onPrimary = Color(0xFFFFFFFF) val md_theme_light_primaryContainer = Color(0xFFC7F089) // .. // .. val md_theme_dark_primary = Color(0xFFACD370) val md_theme_dark_onPrimary = Color(0xFF213600) val md_theme_dark_primaryContainer = Color(0xFF324F00) // .. // ..
Theme.kt
zawiera ustawienia schematów kolorów jasnego i ciemnego oraz motywu aplikacji.
private val LightColorScheme = lightColorScheme( primary = md_theme_light_primary, onPrimary = md_theme_light_onPrimary, primaryContainer = md_theme_light_primaryContainer, // .. ) private val DarkColorScheme = darkColorScheme( primary = md_theme_dark_primary, onPrimary = md_theme_dark_onPrimary, primaryContainer = md_theme_dark_primaryContainer, // .. ) @Composable fun ReplyTheme( darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit ) { val colorScheme = if (!darkTheme) { LightColorScheme } else { DarkColorScheme } MaterialTheme( colorScheme = colorScheme, content = content ) }
Aby obsługiwać jasny i ciemny motyw, użyj isSystemInDarkTheme()
. Na podstawie ustawienia systemu określ, który schemat kolorów ma być używany: jasny czy ciemny.
dynamiczne schematy kolorów.
Kolor dynamiczny jest kluczowym elementem Material You. Algorytm wyprowadza z tapety użytkownika kolory niestandardowe, które są stosowane w aplikacjach i interfejsie systemu. Ta paleta kolorów jest punktem wyjścia do generowania jasnych i ciemnych schematów kolorów.

Dynamiczna kolorystyka jest dostępna w Androidzie 12 i nowszych. Jeśli dynamiczny kolor jest dostępny, możesz skonfigurować dynamiczną ColorScheme
. Jeśli nie, użyj niestandardowego motywu jasnego lub ciemnego ColorScheme
.
ColorScheme
udostępnia funkcje konstruktora do tworzenia dynamicznego schematu kolorów light lub dark:
// Dynamic color is available on Android 12+ val dynamicColor = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S val colors = when { dynamicColor && darkTheme -> dynamicDarkColorScheme(LocalContext.current) dynamicColor && !darkTheme -> dynamicLightColorScheme(LocalContext.current) darkTheme -> DarkColorScheme else -> LightColorScheme }
Używanie kolorów
Kolory motywu Material możesz uzyskać w aplikacji za pomocą:MaterialTheme.colorScheme
Text( text = "Hello theming", color = MaterialTheme.colorScheme.primary )
Każda rola koloru może być używana w różnych miejscach w zależności od stanu, znaczenia i podkreślenia komponentu.
- Kolor podstawowy to kolor bazowy używany w przypadku głównych elementów, takich jak wyróżnione przyciski, aktywne stany i kolory podkreślenia podniesionych powierzchni.
- Używany jest w przypadku mniej widocznych elementów w interfejsie, takich jak elementy filtra, i rozszerza możliwości wyrażania kolorem.
- Trzeci kluczowy kolor służy do określania roli kontrastujących akcentów, które można wykorzystać do zrównoważenia kolorów podstawowych i dodatkowych lub zwrócenia uwagi na element.
W przykładzie interfejsu aplikacji Reply kolor kontenera głównego jest używany na wierzchu kontenera głównego, aby podkreślić wybrany element.

Card( colors = CardDefaults.cardColors( containerColor = if (isSelected) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceVariant ) ) { Text( text = "Dinner club", style = MaterialTheme.typography.bodyLarge, color = if (isSelected) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurface, ) }
W schowku nawigacji odpowiedzi możesz zobaczyć, jak kolory kontenera drugiego i trzeciego rzędu są używane w kontrascie, aby nadać im znaczenie i wyrazistość.

Typografia
Material Design 3 definiuje skalę typograficzną, w tym style tekstu, które zostały zaadaptowane z Material Design 2. Nazewnictwo i grupowanie zostały uproszczone do: wyświetlania, nagłówka, tytułu, tekstu i etykiety w wersji dużej, średniej i małej.

M3 | Domyślny rozmiar czcionki/wysokość linii |
displayLarge |
Roboto 57/64 |
displayMedium |
Roboto 45/52 |
displaySmall |
Roboto 36/44 |
headlineLarge |
Roboto 32/40 |
headlineMedium |
Roboto 28/36 |
headlineSmall |
Roboto 24/32 |
titleLarge |
New- Roboto Medium 22/28 |
titleMedium |
Roboto Medium 16/24 |
titleSmall |
Roboto Medium 14/20 |
bodyLarge |
Roboto 16/24 |
bodyMedium |
Roboto 14/20 |
bodySmall |
Roboto 12/16 |
labelLarge |
Roboto Medium 14/20 |
labelMedium |
Roboto Medium 12/16 |
labelSmall |
New Roboto Medium, 11/16 |
Definiowanie typografii
Compose udostępnia klasę M3 Typography
(oraz istniejące klasy TextStyle
i powiązane z czcionką), aby modelować skalę typu Material 3. Konstruktor Typography
oferuje wartości domyślne dla każdego stylu, dzięki czemu możesz pominąć parametry, których nie chcesz dostosowywać:
val replyTypography = Typography( titleLarge = TextStyle( fontWeight = FontWeight.SemiBold, fontSize = 22.sp, lineHeight = 28.sp, letterSpacing = 0.sp ), titleMedium = TextStyle( fontWeight = FontWeight.SemiBold, fontSize = 16.sp, lineHeight = 24.sp, letterSpacing = 0.15.sp ), // .. ) // ..

Twój produkt prawdopodobnie nie będzie potrzebował wszystkich 15 domyślnych stylów z gamy typów Material Design. W tym przykładzie wybrano 5 rozmiarów do krótszego zestawu, a pozostałe pominięto.
Możesz dostosować typografię, zmieniając domyślne wartości atrybutów TextStyle
i związanych z czcionką, takich jak fontFamily
i letterSpacing
.
bodyLarge = TextStyle( fontWeight = FontWeight.Normal, fontFamily = FontFamily.SansSerif, fontStyle = FontStyle.Italic, fontSize = 16.sp, lineHeight = 24.sp, letterSpacing = 0.15.sp, baselineShift = BaselineShift.Subscript ),
Po zdefiniowaniu Typography
przekaż go do M3 MaterialTheme
:
MaterialTheme( typography = replyTypography, ) { // M3 app Content }
Używanie stylów tekstu
Możesz pobrać typografię udostępnioną w komponentach M3 MaterialTheme
, używając MaterialTheme.typography
:
Text( text = "Hello M3 theming", style = MaterialTheme.typography.titleLarge ) Text( text = "you are learning typography", style = MaterialTheme.typography.bodyMedium )
Więcej informacji o wytycznych Material Design znajdziesz w artykule Stosowanie typografii.
Kształty
Powierzchnie materiałów mogą mieć różne kształty. Kształty przykuwają uwagę, wskazują elementy, informują o stanie i wyrażają charakter marki.
Skala kształtu określa styl rogów kontenera, oferując różne stopnie zaokrąglenia od kwadratu do koła.
Definiowanie kształtów
Compose udostępnia klasę M3 Shapes
z rozszerzonymi parametrami, aby obsługiwać nowe kształty M3. Skala kształtów M3 jest bardziej podobna do skali typu, co umożliwia stosowanie różnych kształtów w interfejsie.
Kształty są dostępne w różnych rozmiarach:
- Bardzo mały
- Mały
- średni,
- Duży
- Bardzo duży
Domyślnie każdy kształt ma wartość domyślną, ale możesz ją zastąpić:
val replyShapes = Shapes( extraSmall = RoundedCornerShape(4.dp), small = RoundedCornerShape(8.dp), medium = RoundedCornerShape(12.dp), large = RoundedCornerShape(16.dp), extraLarge = RoundedCornerShape(24.dp) )
Po zdefiniowaniu Shapes
możesz je przekazać do M3 MaterialTheme
:
MaterialTheme( shapes = replyShapes, ) { // M3 app Content }
Używanie kształtów
Możesz dostosować skalę kształtu dla wszystkich komponentów w MaterialTheme
lub dla poszczególnych komponentów.
Zastosuj kształt średni i duży z wartościami domyślnymi:
Card(shape = MaterialTheme.shapes.medium) { /* card content */ } FloatingActionButton( shape = MaterialTheme.shapes.large, onClick = { } ) { /* fab content */ }

Dostępne są też 2 inne kształty – RectangleShape
i CircleShape
– które są częścią usługi Compose. Prostokąt ma promień zaokrąglenia 0 px, a okrąg ma zaokrąglone krawędzie:
Card(shape = RectangleShape) { /* card content */ } Card(shape = CircleShape) { /* card content */ }
Przykłady poniżej pokazują niektóre komponenty z zaaplikowanymi domyślnymi wartościami kształtu:

Więcej informacji o wytycznych Material Design znajdziesz w sekcji Stosowanie kształtów.
Wyróżnienie
W M3 nacisk jest zaznaczany za pomocą odmian koloru i ich kombinacji. W M3 możesz wyróżnić elementy interfejsu na 2 sposoby:
- Używanie kolorów powierzchni, wariantów powierzchni i tła oraz kolorów powierzchni i wariantów powierzchni z rozszerzonego systemu kolorów M3. Na przykład, surface może być używany z on-surface-variant, a on-surface-variant może być używany z on-surface, aby zapewnić różne poziomy podkreślenia.

- Używanie różnych grubości czcionek. Jak już wiesz, możesz dodać niestandardowe wagi do naszej skali typów, aby nadać im różny nacisk.
bodyLarge = TextStyle( fontWeight = FontWeight.Bold ), bodyMedium = TextStyle( fontWeight = FontWeight.Normal )
Wysokość
Materiał 3 przedstawia wzniesienie głównie za pomocą nakładek kolorów tonalnych. Jest to nowy sposób na rozróżnianie kontenerów i powierzchni od siebie nawzajem – zwiększanie wysokości dźwięku w ramach podnoszenia tonu wykorzystuje bardziej wyrazisty ton, oprócz cieni.

W Material 3.0 nakładki rangi w ciemnych motywach zostały zastąpione nakładkami kolorów tonalnych. Kolor nakładki pochodzi z miejsca na kolor podstawowy.

Powierzchnia w M3 – komponent do komponowania, który jest podstawą większości komponentów M3 – obsługuje zarówno podnoszenie tonalne, jak i cienie:
Surface( modifier = Modifier, tonalElevation = /*... shadowElevation = /*... ) { Column(content = content) }
Komponenty materiału
Material Design zawiera bogaty zestaw elementów interfejsu (np. przycisków, elementów, kart i paska nawigacyjnego), które są już zgodne z wytycznymi Material Theming i pomagają tworzyć piękne aplikacje w stylu Material Design. Możesz od razu zacząć używać komponentów z właściwościami domyślnymi.
Button(onClick = { /*..*/ }) { Text(text = "My Button") }
M3 udostępnia wiele wersji tych samych komponentów do stosowania w różnych rolach w zależności od natężenia i uwzględniania.

- Rozszerzony pływający przycisk polecenia dla działania o najwyższym stopniu podkreślenia:
ExtendedFloatingActionButton( onClick = { /*..*/ }, modifier = Modifier ) { Icon( imageVector = Icons.Default.Edit, contentDescription = stringResource(id = R.string.edit), ) Text( text = stringResource(id = R.string.add_entry), ) }
- Wypełniony przycisk dla działania o wysokim stopniu natężenia:
Button(onClick = { /*..*/ }) { Text(text = stringResource(id = R.string.view_entry)) }
- Przycisk tekstowy z działaniem o mniejszym znaczeniu:
TextButton(onClick = { /*..*/ }) { Text(text = stringResource(id = R.string.replated_articles)) }
Dowiedz się więcej o przyciskach i innych komponentach Material Design. Material 3 oferuje wiele zestawów komponentów, takich jak przyciski, paski aplikacji czy komponenty nawigacji, które są specjalnie zaprojektowane pod kątem różnych zastosowań i rozmiarów ekranu.
Elementy nawigacyjne
Materiał zawiera też kilka komponentów nawigacji, które ułatwiają implementację nawigacji w zależności od różnych rozmiarów i stanów ekranu.
Atrybut NavigationBar
jest używany w przypadku urządzeń kompaktowych, gdy chcesz kierować reklamy na 5 lub mniej miejsc docelowych:
NavigationBar(modifier = Modifier.fillMaxWidth()) { Destinations.entries.forEach { replyDestination -> NavigationBarItem( selected = selectedDestination == replyDestination, onClick = { }, icon = { } ) } }
NavigationRail
jest używany w przypadku małych i średnich tabletów oraz telefonów w orientacji poziomej. Zapewnia ona użytkownikom większą ergonomię i poprawia wrażenia użytkowników tych urządzeń.
NavigationRail( modifier = Modifier.fillMaxHeight(), ) { Destinations.entries.forEach { replyDestination -> NavigationRailItem( selected = selectedDestination == replyDestination, onClick = { }, icon = { } ) } }

BottomNavigationBar
(po lewej) i NavigationRail
(po prawej)Odpowiadaj, używając obu opcji w domyślnym motywie, aby zapewnić użytkownikom wrażenia płynnego korzystania z usługi na urządzeniach o różnych rozmiarach.
NavigationDrawer
jest używany na tabletach o średniej i dużej wielkości, na których jest wystarczająco dużo miejsca na wyświetlanie szczegółów. Możesz użyć właściwości PermanentNavigationDrawer
lub ModalNavigationDrawer
razem z NavigationRail
.
PermanentNavigationDrawer(modifier = Modifier.fillMaxHeight(), drawerContent = { Destinations.entries.forEach { replyDestination -> NavigationRailItem( selected = selectedDestination == replyDestination, onClick = { }, icon = { }, label = { } ) } }) { }

Opcje nawigacji poprawiają wrażenia użytkownika, ergonomię i dostępność. Więcej informacji o komponentach nawigacji w Material Design znajdziesz w kodlabie tworzenia aplikacji dostosowujących się do ekranu.
Dostosowywanie motywu komponentu
M3 zachęca do personalizacji i elastyczności. Wszystkie komponenty mają domyślne kolory, ale w razie potrzeby można je dostosować za pomocą elastycznych interfejsów API.
Większość komponentów, takich jak karty i przyciski, udostępnia domyślny obiekt, który ujawnia interfejsy koloru i wysokości, które można zmodyfikować, aby dostosować komponent:
val customCardColors = CardDefaults.cardColors( contentColor = MaterialTheme.colorScheme.primary, containerColor = MaterialTheme.colorScheme.primaryContainer, disabledContentColor = MaterialTheme.colorScheme.surface, disabledContainerColor = MaterialTheme.colorScheme.onSurface, ) val customCardElevation = CardDefaults.cardElevation( defaultElevation = 8.dp, pressedElevation = 2.dp, focusedElevation = 4.dp ) Card( colors = customCardColors, elevation = customCardElevation ) { // m3 card content }
Więcej informacji o dostosowywaniu Material 3.
interfejs systemu
Niektóre aspekty Material You pochodzą z nowego stylu wizualnego i interfejsu systemu w Androidzie 12 i nowszych. Dwie kluczowe zmiany dotyczą efektu falowania i przewijania ponad ekran. Wdrożenie tych zmian nie wymaga dodatkowych działań.
Marszczenie
Gdy przycisk jest wciśnięty, funkcja Ripple powoduje delikatne migotanie, które oświetla powierzchnię. Kompozycja Material Ripple korzysta z platformy RippleDrawable na Androidzie, więc efekt błysku jest dostępny na Androidzie 12 i nowszych we wszystkich komponentach Material Design.

Overscroll
Przewijanie ponad ekran korzysta teraz z efektu rozciągania na krawędziach przewijanych kontenerów.
Rozciąganie podczas przewijania jest domyślnie włączone w komponentach skompilowanych kontenerów, takich jak LazyColumn
, LazyRow
i LazyVerticalGrid
, w wersji Compose Foundation 1.1.0 lub nowszej, niezależnie od poziomu interfejsu API.

Ułatwienia dostępu
Standardy ułatwień dostępu wbudowane w składniki Material Design mają stanowić podstawę projektowania produktów z uwzględnieniem wszystkich użytkowników. Poznanie dostępności produktu może zwiększyć jego użyteczność dla wszystkich użytkowników, w tym osób z niedowidzeniem, ślepotą, niedosłuchem, zaburzeniami poznawczymi, zaburzeniami ruchowymi lub niepełnosprawnością zależną od sytuacji (np. złamaną ręką).
Dostępność kolorów
Dynamiczne kolory są zgodne ze standardami ułatwień dostępu dotyczącymi kontrastu kolorów. System palet tonalnych jest kluczowy, aby każdy schemat kolorów był dostępny domyślnie.
System kolorów Material udostępnia standardowe wartości i wymiary odcieni, które można wykorzystać do spełnienia wymagań dotyczących kontrastu w dostępności.

Wszystkie komponenty Material Design i dynamiczne motywy używają już tych ról kolorów z zestawu palet tonalnych, które zostały wybrane tak, aby spełniać wymagania dotyczące dostępności. Jeśli jednak dostosowujesz komponenty, pamiętaj, aby używać odpowiednich kolorów i unikać niespójności.
Użyj koloru głównego na wierzchu koloru podstawowego, a kolor głównego na wierzchu kontenera głównego. Zrób to samo w przypadku innych kolorów uzupełniających i neutralnych, aby zapewnić użytkownikowi kontrast ułatwiający dostępność.
Użycie kontenera trzeciego rzędu nałożonego na kontener pierwszego rzędu powoduje, że użytkownik ma do dyspozycji przycisk o złym kontraście:
// ✅ Button with sufficient contrast ratio Button( onClick = { }, colors = ButtonDefaults.buttonColors( containerColor = MaterialTheme.colorScheme.primary, contentColor = MaterialTheme.colorScheme.onPrimary ) ) { } // ❌ Button with poor contrast ratio Button( onClick = { }, colors = ButtonDefaults.buttonColors( containerColor = MaterialTheme.colorScheme.tertiaryContainer, contentColor = MaterialTheme.colorScheme.primaryContainer ) ) { }

Ułatwienia dostępu dotyczące typografii
Skala typu M3 aktualizuje statyczne rampy i wartości typu, aby zapewnić uproszczony, ale dynamiczny schemat kategorii rozmiarów, który dostosowuje się do różnych urządzeń.
Na przykład w M3 można przypisać wyświetlaczowi Small różne wartości w zależności od kontekstu urządzenia, np. telefonu lub tabletu.
Duże ekrany
Material Design zawiera wskazówki dotyczące układów dostosowujących się do urządzenia i urządzeń składanych, które ułatwiają dostęp do aplikacji i zwiększają wygodę użytkowników trzymających duże urządzenia.
Material udostępnia różne rodzaje nawigacji, aby ułatwić Ci zapewnienie użytkownikom wygody na dużych urządzeniach.
Więcej informacji o wskazówkach dotyczących jakości aplikacji na duże ekrany znajdziesz w przykładowej odpowiedzi z uwzględnieniem dostępności i elastycznego projektu.
Więcej informacji
Aby dowiedzieć się więcej o motywach Material Design w Compose, zapoznaj się z tymi materiałami:
Przykładowe aplikacje
Dokumenty
Dokumentacja i kod źródłowy interfejsu API
Filmy
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy obsługa JavaScript jest wyłączona
- Migracja z wersji Material 2 na wersję Material 3 w komponencie
- Material Design 2 w Compose
- Niestandardowe systemy projektowania w Compose