Jetpack Compose oferuje implementację Material Design 3, czyli kolejnej wersji Material Design. Material 3 obejmuje zaktualizowane motywy, komponenty i funkcje personalizacji Material You, takie jak dynamiczny kolor. Jest on spójny z nowym stylem wizualnym i interfejsem systemu w Androidzie 12 i nowszych wersjach.
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 za pomocą adnotacji ExperimentalMaterial3Api
:
// import androidx.compose.material3.ExperimentalMaterial3Api @Composable fun AppComposable() { // M3 composables }
Motywy Material Design
Motyw M3 zawiera te podsystemy: schemat kolorów, typografia i kształty. Gdy dostosujesz te wartości, zmiany zostaną automatycznie odzwierciedlone 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 jest powiązany z paletą 13 tonów, które są używane przez komponenty Material 3. Oto na przykład schemat kolorów dla jasnego motywu Odpowiedz:
Dowiedz się więcej o schematach kolorów i rolach kolorów.
Generuj schematy 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. Możesz to zrobić za pomocą narzędzia Material Theme Builder. Opcjonalnie możesz też wyeksportować kod motywów Compose. Wygenerowane zostaną te pliki:
Color.kt
zawiera kolory motywu ze wszystkimi zdefiniowanymi rolami zarówno dla motywu jasnego, jak i ciemnego.
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 konfigurację jasnych i ciemnych schematów kolorów oraz motyw 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 ustawień systemu określ, czy schemat kolorów ma być jasny, czy ciemny.
dynamiczne schematy kolorów.
Kolor dynamiczny to kluczowy element Material You. Algorytm wyprowadza z tapety użytkownika kolory niestandardowe, które są stosowane w aplikacji i interfejsie systemu. Ta paleta kolorów jest punktem wyjścia do generowania jasnych i ciemnych schematów kolorów.
Dynamiczne kolory są dostępne na Androidzie 12 i nowszych. Jeśli jest dostępny dynamiczny kolor, możesz skonfigurować dynamiczny ColorScheme
. Jeśli nie, wybierz jasny lub ciemny kolor ColorScheme
.
ColorScheme
udostępnia funkcje kreatora do tworzenia dynamicznego schematu kolorów jasnego lub ciemnego:
// 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
Dostęp do kolorów motywu Material Design w aplikacji możesz uzyskać za pomocą MaterialTheme.colorScheme
:
Text( text = "Hello theming", color = MaterialTheme.colorScheme.primary )
Każdej roli koloru można użyć w różnych miejscach w zależności od stanu, widoczności i akcentu komponentu.
- Kolor podstawowy to kolor bazowy używany w przypadku głównych elementów, takich jak wyróżnione przyciski, aktywne stany i kolory podkreślone na podniesionych powierzchniach.
- Dodatkowy kolor klucza jest używany w przypadku mniej widocznych komponentów w interfejsie, takich jak ikony filtra, i zwiększa możliwości wyrażenia koloru.
- Trzeci kluczowy kolor jest używany do określania roli kontrastujących akcentów, które mogą być wykorzystywane do zrównoważenia kolorów podstawowych i dodatkowych lub do zwrócenia uwagi na element.
Projekt przykładowej aplikacji Odpowiedz używa koloru w kontenerze głównym, aby wyróżnić 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, ) }
Tutaj możesz zobaczyć w panelu nawigacji odpowiedzi, jak kontrastuje ze sobą kolory kontenera dodatkowego i trzeciego, aby uzyskać wyróżnienie i akcent.
Typografia
Material Design 3 definiuje skalę typograficzną, w tym style tekstu, które zostały zaadaptowane z Material Design 2. Nazwy i grupy zostały uproszczone do: wyświetlania, nagłówka, tytułu, tekstu i etykiety, w rozmiarach dużym, średnim i małym.
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
wraz z istniejącymi klasami TextStyle
i font-related do modelowania skali Material 3. Konstruktor Typography
oferuje wartości domyślne dla każdego stylu, dzięki czemu możesz pomijać 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 ze skali typu 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 ),
Gdy określisz właściwość Typography
, przekaż ją do MaterialTheme
M3:
MaterialTheme( typography = replyTypography, ) { // M3 app Content }
Używanie stylów tekstu
Możesz pobrać typografię udostępnioną funkcji kompozycyjnej M3 MaterialTheme
, używając polecenia 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 rozwiniętymi parametrami umożliwiającymi obsługę nowych kształtów M3. Skala kształtu M3 przypomina skalę typów, która umożliwia swobodny wybór 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 to zmienić:
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 średni i duży kształt z wartościami domyślnymi:
Card(shape = MaterialTheme.shapes.medium) { /* card content */ } FloatingActionButton( shape = MaterialTheme.shapes.large, onClick = { } ) { /* fab content */ }
Istnieją jeszcze 2 inne kształty – RectangleShape
i CircleShape
– które są częścią usługi Compose. Prostokąt ma zaokrąglone krawędzie, a okrąg ma pełne 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 istnieją 2 sposoby na wyróżnienie interfejsu użytkownika:
- Używanie kolorów powierzchni, powierzchni z wariantami i tła wraz z kolorami powierzchni i wariantów powierzchni z rozszerzonego systemu kolorów M3. Na przykład jako powierzchnię i wariant powierzchni można używać jako powierzchni, a w przypadku elementów na powierzchni - dla różnych poziomów podkreślenia.
- Używanie różnych grubości czcionek. Powyżej zauważyliśmy, że do naszej skali typów można dodać niestandardowe wagi, aby podkreślić różne znaczenie.
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 odróż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 w tonach. 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 podświetlenie tonalne, jak i cienie:
Surface( modifier = Modifier, tonalElevation = /*... shadowElevation = /*... ) { Column(content = content) }
Komponenty materiału
Material Design zawiera bogaty zestaw komponentów Material Design (takich jak przyciski, elementy, karty czy pasek nawigacyjny), które są już zgodne z skaliowaniem Material Design i pomagają tworzyć piękne aplikacje w tym stylu. Możesz od razu zacząć używać komponentów z domyślnymi właściwościami.
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 zachęcający do działania:
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 szeroką gamę komponentów, takich jak przyciski, paski aplikacji i nawigacja, które zostały zaprojektowane z myślą o różnych zastosowaniach i rozmiarach ekranów.
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 na małych i średnich tabletach oraz telefonach w trybie poziomym. Zapewnia ona użytkownikom większą ergonomię i polepsza wrażenia użytkowników tych urządzeń.
NavigationRail( modifier = Modifier.fillMaxHeight(), ) { Destinations.entries.forEach { replyDestination -> NavigationRailItem( selected = selectedDestination == replyDestination, onClick = { }, icon = { } ) } }
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
z uwzględnieniem właściwości NavigationRail
.
PermanentNavigationDrawer(modifier = Modifier.fillMaxHeight(), drawerContent = { Destinations.entries.forEach { replyDestination -> NavigationRailItem( selected = selectedDestination == replyDestination, onClick = { }, icon = { }, label = { } ) } }) { }
Opcje nawigacji zwiększają wygodę użytkowników, ergonomię i dostępność. Więcej informacji o komponentach nawigacyjnych Material Design znajdziesz w ćwiczeniach z programowania adaptacyjnego tworzenia aplikacji.
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 }
Dowiedz się więcej o dostosowywaniu Material 3.
interfejs systemu
Niektóre aspekty Material You pochodzą z nowego stylu wizualnego i interfejsu systemowego na Androidzie 12 i nowszych. 2 kluczowe obszary, w których występują zmiany, to fale i nadmierne przewijanie. Wdrożenie tych zmian nie wymaga żadnych dodatkowych działań.
Marszczenie
Gdy przycisk jest wciśnięty, powoduje teraz delikatne migotanie, aby oświetlić 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 dalekie od przewijania korzysta teraz z efektu rozciągnięcia na krawędzi 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 komponenty Material Design mają zapewnić podstawę do projektowania usług promujących integrację społeczną. 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ą zaprojektowane tak, aby spełniać standardy ułatwień dostępu dotyczące kontrastu kolorów. System palet tonalnych jest kluczowy, aby każdy schemat kolorów był dostępny domyślnie.
System kolorów Material Design pozwala uzyskać standardowe wartości odcieni i pomiary, które pozwalają uzyskać dostępne współczynniki kontrastu.
Wszystkie komponenty Material Design i dynamiczne motywy używają już tych ról kolorów z zestawu palet tonalnych wybranych tak, aby spełniały wymagania dotyczące dostępności. Jeśli jednak dostosowujesz komponenty, użyj odpowiednich ról kolorów i unikaj niezgodności.
Użyj koloru na tle koloru podstawowego i koloru na tle kontenera podstawowego, a także tych samych kolorów 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 przycisk ma słaby kontrast:
// ✅ 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 wersji M3 usłudze Display Small można przypisywać różne wartości w zależności od kontekstu urządzenia, takiego jak telefon czy tablet.
Duże ekrany
W materiałach znajdziesz wskazówki dotyczące adaptacyjnych układów i urządzeń składanych, dzięki którym Twoje aplikacje będą bardziej dostępne, a użytkownicy korzystający z dużych urządzeń będą mogli wygodniej korzystać z tych urządzeń.
Material udostępnia różne rodzaje nawigacji, aby ułatwić użytkownikom korzystanie z dużej aplikacji.
Więcej informacji o wytycznych dotyczących jakości aplikacji na duże ekrany znajdziesz w przykładowej odpowiedzi z uwzględnieniem dostępności.
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