Jetpack Compose udostępnia implementację Material Design 3, czyli nowej ewolucji tego stylu. Material 3 zawiera zaktualizowane motywy, komponenty i funkcje personalizacji Material You, takie jak dynamiczny kolor, i jest spójny z nowym stylem wizualnym oraz interfejsem systemu na Androidzie 12 i nowszych.
Poniżej przedstawiamy wdrożenie interfejsu Material Design 3, korzystając z przykładowej aplikacji Odpowiedz. Przykład odpowiedzi jest oparty w całości na stylu Material Design 3.
Zależność
Aby zacząć korzystać z Material 3 w aplikacji do tworzenia wiadomości, dodaj zależność Utwórz materiał 3 do plików build.gradle
:
implementation "androidx.compose.material3:material3:$material3_version"
Gdy dodasz zależność, 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 }
Tworzenie motywów materiałów
Motyw M3 obejmuje te podsystemy: schemat kolorów, typografia i kształty. Gdy dostosujesz te wartości, zmiany te zostaną automatycznie odzwierciedlone w komponentach M3, których używasz do tworzenia aplikacji.
Jetpack Compose implementuje te koncepcje za pomocą funkcji kompozycyjnej MaterialTheme
M3:
MaterialTheme( colorScheme = /* ... typography = /* ... shapes = /* ... ) { // M3 app content }
Aby ukierunkować treści na treść aplikacji, określ jej schemat kolorów, typografię i kształty.
Schemat kolorów
Podstawą schematu kolorów jest zestaw pięciu kluczowych kolorów. Każdy z tych kolorów odnosi się do palety 13 tonów używanych przez komponenty Material 3. Oto przykład schematu kolorów jasnego motywu Odpowiedz:
Dowiedz się więcej o schematach kolorów i rólach kolorów.
Generuj schematy kolorów
Chociaż możesz utworzyć niestandardowy atrybut ColorScheme
ręcznie, często łatwiej jest wygenerować go za pomocą kolorów źródłowych związanych z Twoją marką. Możesz to zrobić za pomocą narzędzia Material Theme Builder oraz opcjonalnie wyeksportować kod motywu. Wygenerowane zostaną te pliki:
Color.kt
zawiera kolory motywu oraz wszystkie role zdefiniowane dla kolorów jasnego 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 isSystemInDarkTheme()
. W zależności od ustawienia systemu określ, którego schematu kolorów chcesz użyć: jasny czy ciemny.
Dynamiczne schematy kolorów
Dynamiczne kolory to kluczowa część Material You, w której algorytm pobiera niestandardowe kolory na podstawie tapety użytkownika i stosuje je w jego aplikacjach i interfejsie systemu. Ta paleta kolorów służy za punkt wyjścia do generowania jasnych i ciemnych schematów kolorów.
Dynamiczne kolory są dostępne na Androidzie 12 i nowszych. Jeśli kolor dynamiczny jest dostępny, możesz skonfigurować ColorScheme
. Jeśli nie, użyj niestandardowego lub ciemnego ColorScheme
.
ColorScheme
udostępnia funkcje kreatora umożliwiające tworzenie 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 }
Wykorzystanie kolorów
Kolory motywu Material Design są dostępne w aplikacji za pomocą MaterialTheme.colorScheme
:
Text( text = "Hello theming", color = MaterialTheme.colorScheme.primary )
Każdą rolę koloru można użyć w różnych miejscach w zależności od stanu, widoczności i wyróżnienia komponentu.
- Kolor podstawowy to kolor podstawowy używany w przypadku głównych elementów, takich jak widoczne przyciski, stany aktywne i odcień wyniesionych powierzchni.
- Kolor klucza dodatkowego jest używany w przypadku mniej widocznych komponentów interfejsu, takich jak elementy filtra, i zwiększa możliwości ekspresji kolorów.
- Kolor trzeciorzędny służy do określenia ról kontrastujących akcentów, które można wykorzystać do zrównoważenia koloru podstawowego i dodatkowego lub zwiększenia zainteresowania elementem.
Projekt przykładowej aplikacji Odpowiedz wykorzystuje kolor w kontenerze podstawowym, 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, ) }
Widać tutaj, w szufladzie nawigacji odpowiedzi, jak używane są kolory dodatkowe i trzeciorzędne, kontrastujące ze sobą do wzmocnienia przekazu.
Typografia
Material Design 3 określa skalę rodzajów, w tym style tekstu zaadaptowane do stylu Material Design 2. Uprościliśmy nazewnictwo i grupowanie, aby wyglądało tak: „display”, „nagłówek”, „tytuł”, „treść” i „etykieta” (rozmiar 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 |
Zdefiniuj typografię
Funkcja Compose udostępnia klasę Typography
M3 – wraz z istniejącymi klasami TextStyle
i związanymi z czcionkami – do modelowania skali typów Material 3. Konstruktor Typography
podaje 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 stylów domyślnych ze skali typu Material Design. W tym przykładzie dla zmniejszonego zestawu wybrano 5 rozmiarów, a pozostałe zostały pominięte.
Typografię możesz dostosować, zmieniając wartości domyślne właściwości TextStyle
i właściwości związanych z czcionkami, 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 MaterialTheme
M3:
MaterialTheme( typography = replyTypography, ) { // M3 app Content }
Używanie stylów tekstu
Typografię przekazaną w komponencie M3 MaterialTheme
można pobrać, używając funkcji MaterialTheme.typography
:
Text( text = "Hello M3 theming", style = MaterialTheme.typography.titleLarge ) Text( text = "you are learning typography", style = MaterialTheme.typography.bodyMedium )
Możesz dowiedzieć się więcej o wytycznych dotyczących materiału na temat stosowania typografii.
Kształty
Powierzchnie materiałowe mogą mieć różne kształty. Kształtuje uwagę, identyfikuje elementy, przekazuje stan i wyraża markę.
Skala kształtu określa styl narożników kontenera i zapewnia zakres zaokrągleń – od kwadratowego po całkowicie okrągły.
Zdefiniuj kształty
Tworzenie udostępnia klasę Shapes
M3 z rozszerzonymi parametrami umożliwiającymi obsługę nowych kształtów M3. Skala kształtu M3 przypomina skalę typów, która zapewnia ekspresyjny zakres 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 zastąpić te wartości:
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 go przekazać do MaterialTheme
M3:
MaterialTheme( shapes = replyShapes, ) { // M3 app Content }
Używanie kształtów
Możesz dostosować skalę kształtu wszystkich komponentów w narzędziu MaterialTheme
lub zrobić to 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 */ }
Elementem tworzenia są też 2 inne kształty: RectangleShape
i CircleShape
. Prostokątny kształt bez promienia obramowania, a kształt okręgu ma pełne okrągłe krawędzie:
Card(shape = RectangleShape) { /* card content */ } Card(shape = CircleShape) { /* card content */ }
W przykładach poniżej pokazano niektóre komponenty, do których zastosowano domyślne wartości kształtów:
Więcej informacji o wytycznych dotyczących materiałów znajdziesz w artykule o stosowaniu kształtu.
Wyróżnienie
W wersji M3 wyróżniamy kolory i ich kombinacje. W wersji M3 wyróżnia się elementy interfejsu na 2 sposoby:
- Porównanie kolorów powierzchni, wariantu powierzchni i tła z kolorami na powierzchni i na jej powierzchni z rozszerzonego systemu kolorów M3. Typu „Powierzchnia” można na przykład stosować w przypadku wariantu na powierzchni, a wariant na powierzchni – aby uzyskać różne poziomy znaczenia.
- Używanie różnych grubości czcionek w tekście. Powyżej widzimy, że w naszej skali typów można podać własne wagi w celu zróżnicowania znaczenia.
bodyLarge = TextStyle( fontWeight = FontWeight.Bold ), bodyMedium = TextStyle( fontWeight = FontWeight.Normal )
Wysokość
Materiał 3 przedstawia wysokość głównie za pomocą nakładek w kolorach tonalnych. To nowy sposób na rozróżnianie kontenerów i płaszczyzn od siebie – oprócz cieni zwiększenie wysokości tonalnego skutkuje też bardziej wyraźnym tonem.
Nakładki wysokości w ciemnych motywach zostały też zmienione na nakładki z kolorami tonalnymi w Material 3. Kolor nakładki pochodzi z boksu koloru podstawowego.
Powierzchnia M3 – czyli kompozycje tworzące podkład w większości komponentów M3 – obejmuje obsługę wysokości tonów i cieni:
Surface( modifier = Modifier, tonalElevation = /*... shadowElevation = /*... ) { Column(content = content) }
Komponenty
Material Design obejmuje bogaty zestaw komponentów Material Design (takich jak przyciski, układy scalone, karty i pasek nawigacyjny), które są zgodne ze stylem Material Design, i pomagają tworzyć atrakcyjne 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 zawiera wiele wersji tych samych komponentów, które można wykorzystać w różnych rolach pod względem podkreślania i uwagi.
- Rozszerzony pływający przycisk polecenia wyświetlający działanie z najwyższym naciskiem:
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 działania z wysokim naciskiem:
Button(onClick = { /*..*/ }) { Text(text = stringResource(id = R.string.view_entry)) }
- Przycisk tekstowy przedstawiający działanie z niewielkim naciskiem:
TextButton(onClick = { /*..*/ }) { Text(text = stringResource(id = R.string.replated_articles)) }
Dowiedz się więcej o przyciskach Material Design i innych komponentach. W Material 3 znajdziesz wiele różnych zestawów komponentów, takich jak przyciski, paski aplikacji czy komponenty nawigacji, które zostały zaprojektowane z myślą o różnych zastosowaniach i rozmiarach ekranów.
Komponenty nawigacji
Zawiera też kilka komponentów nawigacyjnych, które ułatwiają wdrażanie nawigacji w zależności od rozmiaru i stanu ekranu.
Parametr NavigationBar
jest używany w przypadku urządzeń kompaktowych, jeśli chcesz kierować reklamy na maksymalnie 5 miejsc docelowych:
NavigationBar(modifier = Modifier.fillMaxWidth()) { Destinations.entries.forEach { replyDestination -> NavigationBarItem( selected = selectedDestination == replyDestination, onClick = { }, icon = { } ) } }
Aplikacja NavigationRail
jest używana na małych i średnich tabletach lub telefonach w orientacji poziomej. Zapewnia ergonomię użytkownikom i poprawia wrażenia użytkowników korzystających z tych urządzeń.
NavigationRail( modifier = Modifier.fillMaxHeight(), ) { Destinations.entries.forEach { replyDestination -> NavigationRailItem( selected = selectedDestination == replyDestination, onClick = { }, icon = { } ) } }
Odpowiadaj, używając obu domyślnych tematów, aby zapewnić odbiorcom atrakcyjne wrażenia na urządzeniach wszystkich rozmiarów.
Format NavigationDrawer
jest używany na średnich i dużych tabletach, na których masz wystarczająco dużo miejsca, aby pokazywać szczegóły. Możesz używać zarówno właściwości PermanentNavigationDrawer
, jak i ModalNavigationDrawer
razem z zasadą 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 osiągalność. Więcej informacji o komponentach nawigacji Material Design znajdziesz w ćwiczeniach z programowania w przypadku tworzenia adaptacyjnych aplikacji.
Dostosowywanie motywu komponentu
M3 zachęca do personalizacji i elastyczności. Wszystkie komponenty mają przypisane kolory domyślne, ale w razie potrzeby dostępne są elastyczne interfejsy API, które pozwalają dostosować kolory.
Większość komponentów, takich jak karty i przyciski, zawiera domyślny interfejs pokazujący kolor i wysokość, które można dostosować, 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 elementy Material You pochodzą z nowego stylu wizualnego i interfejsu systemu na Androidzie 12 i nowszych. Dwoma głównymi obszarami, w których pojawiają się zmiany, są fale i nadmierne przewijanie. Nie musisz nic więcej robić, aby wprowadzić te zmiany.
Marszczenie
Echo podświetla teraz powierzchnie po naciśnięciu delikatną błyszką. Funkcja Compose Material Ripple korzysta z wbudowanej platformy RippleDrawable na Androidzie, dlatego ta funkcja jest dostępna na Androidzie 12 i nowszych we wszystkich komponentach Material.
Nadmierne przewijanie
Nadmiarowe przewijanie używa teraz efektu rozciągnięcia przy krawędzi przewijanych kontenerów.
Rozciąganie nadmiarowego przewijania jest domyślnie włączone w elementach kompozycyjnych przewijanych kontenerów – na przykład LazyColumn
, LazyRow
i LazyVerticalGrid
– w 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ę projektowania produktów promujących integrację społeczną. Znajomość ułatwień dostępu w usłudze może ułatwić korzystanie z niej wszystkim użytkownikom, w tym osobom niedowidzącym, niewidomym, niedosłyszącym, niedosłyszącym, niedosłyszącym, niepełnosprawnym ruchowo lub niepełnosprawnym sytuacyjnym (np. złamanym ręką).
Dostępność kolorów
Kolory dynamiczne zostały zaprojektowane tak, aby spełniały standardy ułatwień dostępu dotyczące kontrastu kolorów. System palet tonalnych ma kluczowe znaczenie dla domyślnego dostępu do każdego schematu kolorów.
System kolorów materiału udostępnia standardowe wartości odcieni i pomiary, których można użyć do uzyskania dostępnych współczynników kontrastu.
Wszystkie komponenty Material Design i dynamiczne motywy korzystają już z powyższych ról kolorów z zestawu palet tonalnych, wybranych zgodnie z wymaganiami ułatwień dostępu. Jeśli jednak dostosowujesz komponenty, użyj odpowiednich ról i unikaj niedopasowania.
Tej opcji należy używać nad kontenerem podstawowym i kontenerem głównym nad kontenerem głównym. Tego samego ustawienia należy użyć w przypadku innych kolorów uzupełniających i neutralnych, aby zapewnić użytkownikom lepszy kontrast.
Użycie kontenera trzeciorzędnego nad elementem podstawowym powoduje, że użytkownik widzi przycisk słabego 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 ) ) { }
Ułatwienia dostępu w typografii
Skala typu M3 aktualizuje statyczną rampę i wartości, tworząc uproszczoną, ale dynamiczną strukturę kategorii rozmiarów, które skalują się na różnych urządzeniach.
Na przykład w wersji M3 małemu wyświetlaczowi można przypisywać różne wartości w zależności od kontekstu urządzenia, takiego jak telefon czy tablet.
Duże ekrany
Materiał zawiera wskazówki dotyczące adaptacyjnych układów i urządzeń składanych, dzięki czemu aplikacje są łatwo dostępne i które poprawiają ergonomię użytkowników korzystających z dużych urządzeń.
Material umożliwia korzystanie z różnych sposobów nawigacji, które ułatwiają użytkownikom korzystanie z dużych urządzeń.
Dowiedz się więcej o wskazówkach dotyczących jakości aplikacji na duży ekran na Androidzie i przeczytaj przykładową odpowiedź, aby dowiedzieć się, jak projekt jest przystępny i adaptacyjny.
Więcej informacji
Więcej informacji o tematowaniu materiałów z motywem Material Design w usłudze Compose znajdziesz w tych materiałach:
Przykładowe aplikacje
Dokumenty
Dokumentacja API i kod źródłowy
- Dokumentacja interfejsu API Compose Material 3
- Tworzenie przykładowego materiału Material 3 w kodzie źródłowym
Filmy
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy JavaScript jest wyłączony
- Migracja z Material 2 do Material 3 w sekcji Utwórz
- Material Design 2 w obszarze Utwórz
- Niestandardowe systemy projektowania w usłudze Compose