W Jetpack Compose dostępna jest implementacja Material Design 3, która stanowi kolejną wersję Material Design. Material 3 ma zaktualizowane motywy, komponenty i funkcje personalizacji Material You, takie jak dynamiczne kolory. Został zaprojektowany tak, aby był spójny z nowym stylem wizualnym i interfejsem systemu na Androidzie 12 i nowszych.
Poniżej pokazujemy implementację Material Design 3 za pomocą przykładowej aplikacji Reply. Przykładowy kod odpowiedzi jest w całości 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 API M3 są uznawane za eksperymentalne. W takich przypadkach musisz wyrazić zgodę na poziomie funkcji lub pliku za pomocą adnotacji ExperimentalMaterial3Api
:
// import androidx.compose.material3.ExperimentalMaterial3Api @OptIn(ExperimentalMaterial3Api::class) @Composable fun AppComposable() { // M3 composables }
Motywy Material Design
Motyw M3 obejmuje 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.
W Jetpack Compose za pomocą funkcji kompozycyjnej M3 MaterialTheme
implementuje ona te koncepcje:
MaterialTheme( colorScheme = /* ... typography = /* ... shapes = /* ... ) { // M3 app content }
Aby motywować zawartość aplikacji, określ schemat kolorów, typografię i kształty odpowiednie dla Twojej aplikacji.
Schemat kolorów
Podstawą schematu kolorów jest zestaw 5 głównych 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
Chociaż niestandardowy ColorScheme
możesz utworzyć ręcznie, często łatwiej jest wygenerować go z użyciem kolorów źródłowych 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 wraz ze wszystkimi rolami zdefiniowanymi zarówno w przypadku 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 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ć jasne i ciemne motywy, użyj funkcji isSystemInDarkTheme()
. Na podstawie ustawień systemu określ, którego schematu kolorów chcesz użyć: jasnego czy ciemnego.
Dynamiczne schematy kolorów
Dynamiczny kolor to kluczowy element Material You. W tym algorytmie algorytm wybiera niestandardowe kolory z tapety użytkownika, które są stosowane do aplikacji i interfejsu systemu. Ta paleta kolorów jest używana jako punkt 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życie 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.
- Główny to kolor podstawowy używany w przypadku głównych komponentów, takich jak widoczne przyciski, stany aktywne i odcień podniesionych powierzchni.
- 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.
- Kolor trzeci jest używany do określenia ról kontrastujących akcentów, które można wykorzystać, aby zrównoważyć kolor podstawowy i dodatkowy lub zwiększyć uwagę elementu.
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 określa skalę typów, w tym style tekstu, które zostały zaadaptowane z interfejsu Material Design 2. Uprościliśmy nazewnictwo i grupowanie w taki sposób, aby wyświetlać, nagłówek, tytuł, treść i etykietę. W przypadku każdego z nich dostępne są rozmiary: duży, średni i mały.
M3, | Domyślny rozmiar czcionki/wysokość wiersza |
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 czcionkami do modelowania skali typu Material 3. Konstruktor Typography
oferuje wartości domyślne dla poszczególnych stylów, więc 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 ze skali typu Material Design. W tym przykładzie wybieramy 5 rozmiarów do ograniczonego zestawu i pominięto reszta.
Typografię możesz dostosować, zmieniając wartości domyślne właściwości TextStyle
i właściwości związane z czcionkami, takie 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 dotyczących materiałów znajdziesz w artykule o stosowaniu typografii.
Kształty
Powierzchnie materiałowe mogą być wyświetlane w różnych kształtach. Kształtują kierują uwagę, identyfikują komponenty, przekazują stan i wyrażają markę.
Skala kształtu określa styl narożników kontenera, zapewniając szeroki zakres zaokrągleń od kwadratowego do pełnego okrągłego.
Zdefiniuj kształty
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.
Istnieją różne rozmiary kształtów:
- 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) )
Zdefiniowany Shapes
możesz przekazać do narzędzia MaterialTheme
M3:
MaterialTheme( shapes = replyShapes, ) { // M3 app Content }
Używanie kształtów
Możesz dostosować skalę kształtu dla wszystkich komponentów w MaterialTheme
lub zrobić to oddzielnie dla każdego komponentu.
Zastosuj średnie i duże kształty z wartościami domyślnymi:
Card(shape = MaterialTheme.shapes.medium) { /* card content */ } FloatingActionButton( shape = MaterialTheme.shapes.large, onClick = { } ) { /* fab content */ }
Istnieją też 2 inne kształty – RectangleShape
i CircleShape
– które są częścią funkcji Compose. Prostokąt nie ma promienia obramowania, a kształt koła ma pełne okręgi:
Card(shape = RectangleShape) { /* card content */ } Card(shape = CircleShape) { /* card content */ }
W przykładach poniżej pokazano niektóre komponenty z zastosowanymi domyślnymi wartościami kształtu:
Więcej informacji na temat stosowania kształtu znajdziesz w wytycznych dotyczących Materiałów.
Wyróżnienie
Nacisk w M3 jest oparty na różnych kombinacjach kolorów i ich kombinacjach. W wersji M3 istnieją 2 sposoby na wyróżnienie interfejsu użytkownika:
- Użycie kolorów powierzchni, wariantu powierzchni i tła oraz kolorów elementów na powierzchni z rozszerzonego systemu kolorów M3. Na przykład jako warstwę powierzchnię i wariancję na powierzchni można wykorzystać w przypadku opcji „na powierzchnia”, a w przypadku elementów na powierzchni uwidaczniać ją na różne sposoby.
- używanie różnych grubości czcionki w tekście. Powyżej zauważyliśmy, że do naszej skali typów można przypisać niestandardowe wagi, aby podkreślić różne znaczenie.
bodyLarge = TextStyle( fontWeight = FontWeight.Bold ), bodyMedium = TextStyle( fontWeight = FontWeight.Normal )
Wysokość
Materiał 3 reprezentuje wysokość głównie za pomocą nakładek w tonach. To nowy sposób odróżniania od siebie kontenerów i płaszczyzn – zwiększanie wysokości tonacji wykorzystuje ton, a nie tylko cienie.
Nakładki wysokości w ciemnych motywach zmieniły się też w kolorowe nakładki w Material 3. Kolor nakładki pochodzi z głównego boksu koloru.
Powierzchnia M3 – kompozycyjna baza za większością komponentów M3 – umożliwia obsługę zarówno uwydatnienia tonalnego, jak i cienia:
Surface( modifier = Modifier, tonalElevation = /*... shadowElevation = /*... ) { Column(content = content) }
Składniki materiałowe
Material Design ma szeroką gamę komponentów Material Design (takich jak przyciski, elementy, karty czy pasek nawigacyjny), które są już zgodne z Material Design i pomagają tworzyć piękne aplikacje w stylu Material Design. Komponenty z właściwościami domyślnymi możesz od razu zacząć używać.
Button(onClick = { /*..*/ }) { Text(text = "My Button") }
M3 udostępnia wiele wersji tych samych komponentów do wykorzystania w różnych rolach ukierunkowanych na przyciąganie uwagi i uwagę.
- Rozszerzony pływający przycisk polecenia zapewniający najwyższy stopień 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 do działania z niewielkim naciskiem:
TextButton(onClick = { /*..*/ }) { Text(text = stringResource(id = R.string.replated_articles)) }
Więcej informacji o przyciskach Material Design i innych komponentach znajdziesz w tym artykule. 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.
Komponenty nawigacyjne
Material Material Design ma też kilka komponentów nawigacyjnych, które pomagają wdrożyć nawigację w zależności od rozmiaru i stanu ekranu.
NavigationBar
jest używany w przypadku urządzeń kompaktowych, gdy chcesz kierować reklamy na maksymalnie 5 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 użytkownikom ergonomię i poprawia wygodę korzystania z tych urządzeń.
NavigationRail( modifier = Modifier.fillMaxHeight(), ) { Destinations.entries.forEach { replyDestination -> NavigationRailItem( selected = selectedDestination == replyDestination, onClick = { }, icon = { } ) } }
Odpowiedz, używając obu w domyślnych motywach, aby zapewnić użytkownikom atrakcyjne wrażenia na wszystkich urządzeniach.
NavigationDrawer
jest używany w przypadku średnich i dużych tabletów, na których jest wystarczająco dużo miejsca na wyświetlanie szczegółów. Możesz używać zarówno PermanentNavigationDrawer
, jak i ModalNavigationDrawer
razem z atrybutem 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ą zastosowane kolory domyślne, ale w razie potrzeby udostępniają elastyczne interfejsy API do dostosowania ich kolorów.
Większość komponentów, np. karty i przyciski, zawiera domyślne interfejsy wyświetlania 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
Echo używa teraz subtelnego iskierki, aby podświetlać powierzchnie po naciśnięciu. Compose Material Ripple korzysta z platformy RippleDrawable znajdującej się wewnątrz systemu Android, dlatego iskierowana fala jest dostępna na Androidzie 12 i nowszych w przypadku wszystkich komponentów Material.
Przewijanie nadmiernie
Przewijanie dalekie od przewijania korzysta teraz z efektu rozciągnięcia na krawędzi przewijanych kontenerów.
Rozciąganie dalekiego przewijania jest domyślnie włączone w funkcjach kompozycyjnych kontenerów przewijanych (na przykład LazyColumn
, LazyRow
i LazyVerticalGrid
) w interfejsie Compose Foundation w wersji 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ą. Znajomość ułatwień dostępu w usłudze może ułatwić jej obsługę wszystkim użytkownikom, m.in. osobom niedowidzącym, niewidomym, niedosłyszącym, niedosłyszącym, niepełnosprawnością ruchową lub niepełnosprawnością sytuacyjną (np. złamaną ręką).
Ułatwienia dostępu w kolorach
Dynamiczne kolory zostały zaprojektowane tak, aby spełniać standardy ułatwień dostępu związane z kontrastem kolorów. System palet tonalnych ma kluczowe znaczenie, jeśli chcesz, aby każdy schemat kolorów był domyślnie dostępny.
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ż powyższych ról kolorów z zestawu palet tonalnych wybranych tak, aby spełniały wymagania ułatwień dostępu. Jeśli jednak dostosowujesz komponenty, użyj odpowiednich ról kolorów i unikaj niezgodności.
Ustaw ten jako główny nad kontenerem głównym i kontener główny nad kontenerem głównym oraz użyj tej samej dla innych kolorów uzupełniających i neutralnych, aby zapewnić odpowiedni kontrast dla użytkownika.
Użycie kontenera trzeciorzędnego nad główną bazą zapewnia użytkownikowi przycisk niskiego kontrastu:
// ✅ 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 ) ) { }
Dostępność typografii
Skala typu M3 aktualizuje statyczną rampę i wartości, aby zapewnić uproszczoną, ale dynamiczną strukturę kategorii rozmiarów skalowanych na różnych urządzeniach.
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, którzy mają duże urządzenia, będą mogli korzystać z nich bardziej ergonomicznie.
Material obejmuje różne rodzaje nawigacji, które pozwalają zapewnić użytkownikom lepsze wrażenia na dużych urządzeniach.
Zapoznaj się ze wskazówkami dotyczącymi jakości aplikacji na Androida na dużym ekranie oraz z naszą przykładową odpowiedzią znajdziesz informacje o dostosowywaniu stron z ułatwieniami dostępu i adaptacji.
Więcej informacji
Aby dowiedzieć się więcej o dobieraniu motywów Material Design w Compose, zapoznaj się z tymi materiałami:
Przykładowe aplikacje
Dokumenty
Dokumentacja API i kod źródłowy
Filmy
Polecane dla Ciebie
- Uwaga: tekst linku wyświetla się, gdy JavaScript jest wyłączony
- Migracja z Material 2 do Material 3 w usłudze Compose
- Material Design 2 w Compose
- Niestandardowe systemy projektowania w Compose