W Jetpack Compose dostępna jest implementacja Material Design, czyli kompleksowego systemu projektowania cyfrowych interfejsów. komponenty Material Design (przyciski, karty, przełączniki itp.); opiera się na technologii Material Design, która pozwala systematycznie dostosować styl Material Design, aby lepiej odzwierciedlał markę Twojego produktu. Materiał Motyw zawiera atrybuty color, typografia i kształt. Gdy dostosujesz te zmiany są automatycznie odzwierciedlane w używanych przez Ciebie komponentach aby stworzyć aplikację.
Jetpack Compose wdraża te koncepcje za pomocą MaterialTheme
funkcja kompozycyjna:
MaterialTheme( colors = // ... typography = // ... shapes = // ... ) { // app content }
Skonfiguruj parametry, które przekazujesz do usługi MaterialTheme
, aby utworzyć motyw aplikacji.
Rysunek 1. Pierwszy zrzut ekranu przedstawia aplikację, która nie została skonfigurowana.
MaterialTheme
, więc jest w nim używany styl domyślny. Na drugim zrzucie ekranu widać
aplikację, która przekazuje parametry do MaterialTheme
, aby dostosować styl.
Kolor
Kolory są modelowane w funkcji Compose za pomocą klasy Color
,
klasy przechowywania danych.
val Red = Color(0xffff0000) val Blue = Color(red = 0f, green = 0f, blue = 1f)
Możesz je uporządkować w dowolny sposób (jako stałe najwyższego poziomu (pojedynczy lub zdefiniowany w treści) zdecydowanie zalecamy określenie kolorów w z motywu i pobierania kolorów. Takie podejście sprawia, z łatwością obsługi ciemnego motywu i motywów zagnieżdżonych.
Rysunek 2. System kolorów Material
Funkcja tworzenia wiadomości udostępnia Colors
do modelowania
System kolorów Material Design Colors
oferuje
funkcji kreatora do tworzenia zbiorów light
lub ciemne
kolory:
private val Yellow200 = Color(0xffffeb46) private val Blue200 = Color(0xff91a4fc) // ... private val DarkColors = darkColors( primary = Yellow200, secondary = Blue200, // ... ) private val LightColors = lightColors( primary = Yellow500, primaryVariant = Yellow400, secondary = Blue700, // ... )
Zdefiniowane Colors
możesz przekazać do MaterialTheme
:
MaterialTheme( colors = if (darkTheme) DarkColors else LightColors ) { // app content }
Używanie kolorów motywu
Możesz pobrać Colors
dostarczone do funkcji kompozycyjnej MaterialTheme
udostępnianej przez
za pomocą funkcji MaterialTheme.colors
.
Text( text = "Hello theming", color = MaterialTheme.colors.primary )
Kolor powierzchni i treści
Wiele komponentów ma parę kolorów do koloru treści:
Surface( color = MaterialTheme.colors.surface, contentColor = contentColorFor(color), // ... ) { /* ... */ } TopAppBar( backgroundColor = MaterialTheme.colors.primarySurface, contentColor = contentColorFor(backgroundColor), // ... ) { /* ... */ }
Dzięki temu możesz nie tylko ustawić kolor elementu kompozycyjnego, ale też określić
domyślny kolor treści, czyli elementów kompozycyjnych, które się w nich znajdują. Wiele
w elementach kompozycyjnych domyślnie używany jest ten kolor treści. Na przykład Text
opiera się na
jest do koloru treści elementu nadrzędnego, a Icon
używa go do określenia jego
zabarwienie.
Rysunek 3. Ustawienie różnych kolorów tła powoduje zmianę kolorów tekstu i ikon.
contentColorFor()
pobiera odpowiednią wartość „on”
dla dowolnych kolorów motywu. Jeśli na przykład ustawisz kolor tła primary
,
w Surface
, używa tej funkcji do ustawiania onPrimary
jako treści
koloru. Jeśli ustawisz kolor tła inny niż motyw, musisz też określić
odpowiedni kolor treści. Użyj formatu LocalContentColor
aby pobrać preferowany kolor treści dla bieżącego tła, na
dane miejsce w hierarchii.
Treść alfa
Często chcesz zróżnicować to, w jakim stopniu podkreślasz treść, aby podkreślić ich znaczenie i zapewnić wizualną hierarchię. Czytelność tekstu w stylu Material Design zalecenia Zastosowanie różnych poziomów przezroczystości w celu określenia odmiennych poziomów ważności.
Jetpack Compose implementuje tę funkcję za pomocą LocalContentAlpha
.
Możesz określić wersję alfa treści w hierarchii, podając wartość
dla: CompositionLocal
.
Zagnieżdżone
funkcje kompozycyjne mogą użyć tej wartości, by zastosować do swoich treści kod alfa.
Na przykład: Text
.
i Icon
domyślnie użyj kombinacji funkcji LocalContentColor
dostosowanej do korzystania z LocalContentAlpha
. Materiał zawiera niektóre standardowe wartości alfa (high
, medium
,
disabled
), które są modelowane przez obiekt ContentAlpha
.
// By default, both Icon & Text use the combination of LocalContentColor & // LocalContentAlpha. De-emphasize content by setting content alpha CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) { Text( // ... ) } CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.disabled) { Icon( // ... ) Text( // ... ) }
Aby dowiedzieć się więcej o tym wyniku (CompositionLocal
), zapoznaj się z danymi w zakresie lokalnym zawierającym
CompositionLocal – przewodnik.
Rysunek 4. Zastosuj różne poziomy uwydatnienia tekstu, aby wizualnie przedstawić
w hierarchii informacji. Pierwszy wiersz tekstu to tytuł i element
najważniejsze informacje, dzięki czemu korzysta z funkcji ContentAlpha.high
. Druga
wiersz zawiera mniej ważne metadane, więc używa ContentAlpha.medium
.
Ciemny motyw
W funkcji Compose implementujesz jasne i ciemne motywy, dodając różne zestawy
Colors
do funkcji kompozycyjnej MaterialTheme
:
@Composable fun MyTheme( darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit ) { MaterialTheme( colors = if (darkTheme) DarkColors else LightColors, /*...*/ content = content ) }
W tym przykładzie funkcja MaterialTheme
jest zawarta we własnej funkcji kompozycyjnej,
który akceptuje parametr określający, czy należy użyć ciemnego motywu. W
w tym przypadku funkcja otrzyma domyślną wartość parametru darkTheme
, wysyłając zapytanie do
ustawienie motywu urządzenia.
Aby sprawdzić, czy bieżące pola Colors
są jasne, czy ciemne, możesz użyć tego kodu:
val isLightTheme = MaterialTheme.colors.isLight Icon( painterResource( id = if (isLightTheme) { R.drawable.ic_sun_24 } else { R.drawable.ic_moon_24 } ), contentDescription = "Theme" )
Nakładki wysokościowe
W sekcji Material powierzchnie z ciemnym motywem i wyższymi wzniesieniami otrzymują nakładki wysokościowe, rozjaśnia tło. Wyższe wysokość powierzchni (podniesienie jej bliżej) do domniemanego źródła światła), tym jaśniejsza staje się powierzchnia.
Te nakładki są stosowane automatycznie przez funkcję kompozycyjną Surface
podczas korzystania
ciemnych kolorów, a w przypadku innych elementów Material Design, w których jest używana powierzchnia:
Surface( elevation = 2.dp, color = MaterialTheme.colors.surface, // color will be adjusted for elevation /*...*/ ) { /*...*/ }
Rysunek 5. Karty i dolne elementy nawigacyjne mają kolor surface
jako tło. Karty i dolne elementy nawigacyjne różnią się od siebie
poziomy są nieco inne niż w przypadku tła
kolorów – karty są jaśniejsze niż tło, a dolna nawigacja jest
lżejsze od kart.
W przypadku niestandardowych scenariuszy, które nie wymagają Surface
, użyj
LocalElevationOverlay
,
CompositionLocal
zawierający
ElevationOverlay
.
używane przez
Surface
komponenty:
// Elevation overlays // Implemented in Surface (and any components that use it) val color = MaterialTheme.colors.surface val elevation = 4.dp val overlaidColor = LocalElevationOverlay.current?.apply( color, elevation )
Aby wyłączyć nakładki wzniesień, podaj null
w wybranym punkcie w polu
hierarchia kompozycyjna:
MyTheme { CompositionLocalProvider(LocalElevationOverlay provides null) { // Content without elevation overlays } }
limitowane akcenty kolorystyczne,
W materiale zaleca się użycie ograniczonego koloru
akcenty – ciemny
motywów, preferując użycie koloru surface
zamiast primary
w większości przypadków. Materiały kompozycyjne Material Design, takie jak TopAppBar
i BottomNavigation
zaimplementuj takie działanie domyślnie.
Rysunek 6. Ciemny motyw Material Design z ograniczonymi akcentami kolorystycznymi. Górny pasek aplikacji korzysta z koloru głównego w jasnym motywie, a kolor powierzchni w ciemnym motywie.
W przypadku niestandardowych scenariuszy użyj interfejsu primarySurface
właściwość rozszerzenia:
Surface( // Switches between primary in light theme and surface in dark theme color = MaterialTheme.colors.primarySurface, /*...*/ ) { /*...*/ }
Typografia
Materiał określa typ , zachęca do stosowania niewielkiej liczby stylów z nazwami semantycznymi.
Rysunek 7. System typów materiału.
Narzędzie Compose implementuje system typów z klasami Typography
, TextStyle
i czcionkami. Konstruktor Typography
oferuje wartości domyślne dla każdego stylu, więc możesz pominąć te, których nie chcesz dostosowywać:
val raleway = FontFamily( Font(R.font.raleway_regular), Font(R.font.raleway_medium, FontWeight.W500), Font(R.font.raleway_semibold, FontWeight.SemiBold) ) val myTypography = Typography( h1 = TextStyle( fontFamily = raleway, fontWeight = FontWeight.W300, fontSize = 96.sp ), body1 = TextStyle( fontFamily = raleway, fontWeight = FontWeight.W600, fontSize = 16.sp ) /*...*/ ) MaterialTheme(typography = myTypography, /*...*/) { /*...*/ }
Jeśli chcesz używać tego samego kroju czcionki, określ
defaultFontFamily parameter
i pomiń fontFamily
wszystkich elementów TextStyle
:
val typography = Typography(defaultFontFamily = raleway) MaterialTheme(typography = typography, /*...*/) { /*...*/ }
Korzystanie ze stylów tekstu
Elementy TextStyle
są otwierane przez: MaterialTheme.typography
. Pobierz
Podobało się to TextStyle
osobom:
Text( text = "Subtitle2 styled", style = MaterialTheme.typography.subtitle2 )
Rysunek 8. Wyraź swoją markę, używając różnych krojów i stylów.
Kształt
Materiał określa systemu kształtu, do definiowania kształtów dla dużych, średnich i małych komponentów.
Rysunek 9. System kształtów Material Design.
Narzędzie Compose implementuje system kształtów za pomocą funkcji
Shapes
, która pozwala
określasz
CornerBasedShape
w każdej kategorii rozmiaru:
val shapes = Shapes( small = RoundedCornerShape(percent = 50), medium = RoundedCornerShape(0f), large = CutCornerShape( topStart = 16.dp, topEnd = 0.dp, bottomEnd = 0.dp, bottomStart = 16.dp ) ) MaterialTheme(shapes = shapes, /*...*/) { /*...*/ }
Wiele komponentów domyślnie używa tych kształtów. Przykład:
Button
TextField
i
FloatingActionButton
na małe,
AlertDialog
domyślna wartość to średnia,
ModalDrawer
.
domyślnie jest ustawiona na duży rozmiar – zobacz
dokumentacja schematu kształtu
aby uzyskać pełne mapowanie.
Korzystanie z kształtów
Elementy Shape
są otwierane przez: MaterialTheme.shapes
. Odzyskaj Shape
za pomocą
podobny do tego:
Surface( shape = MaterialTheme.shapes.medium, /*...*/ ) { /*...*/ }
Rysunek 10. Używaj kształtów do przedstawienia marki lub stanu.
Style domyślne
Nie ma analogicznego pojęcia w funkcji Compose style domyślne w widokach Androida. Możesz zapewnić podobną funkcjonalność, tworząc własne „przeciążone” funkcje kompozycyjne opakowujące komponenty Material. Aby na przykład utworzyć styl przycisku, umieść przycisk we własnej funkcji kompozycyjnej, bezpośrednio ustaw parametry, które chcesz zmienić, i przedstaw inne parametry funkcji kompozycyjnej, która zawiera.
@Composable fun MyButton( onClick: () -> Unit, modifier: Modifier = Modifier, content: @Composable RowScope.() -> Unit ) { Button( colors = ButtonDefaults.buttonColors( backgroundColor = MaterialTheme.colors.secondary ), onClick = onClick, modifier = modifier, content = content ) }
Nakładki motywu
Możesz osiągnąć
nakładki motywów z widoków Androida w Compose, zagnieżdżając
Elementy kompozycyjne MaterialTheme
. Ponieważ
MaterialTheme
domyślnie ustawia kolory, typografię i kształty na bieżącą wartość motywu. Jeśli motyw ustawi tylko jeden z tych parametrów, pozostałe parametry zachowają wartości domyślne.
Ponadto podczas przenoszenia ekranów opartych na widoku do Compose zwróć uwagę na użycie atrybutu android:theme
. Prawdopodobnie potrzebny jest nowy
MaterialTheme
w tej części drzewa interfejsu tworzenia wiadomości.
W tym przykładzie ekran szczegółów korzysta z PinkTheme
na większości ekranu, a potem BlueTheme
dla powiązanej sekcji. Zrzut ekranu i kod znajdziesz poniżej.
Rysunek 11. Zagnieżdżone motywy.
@Composable fun DetailsScreen(/* ... */) { PinkTheme { // other content RelatedSection() } } @Composable fun RelatedSection(/* ... */) { BlueTheme { // content } }
Stany komponentu
Komponenty materiałowe, z którymi można wchodzić w interakcje (klikać, przełączać itp.) w różnych stanach wizualnych. Możliwe stany to: „Włączone”, „Wyłączone”, „Naciśnięte” itd.
Elementy kompozycyjne często mają parametr enabled
. Ustawienie go na false
zapobiega
interakcji oraz zmienia właściwości, takie jak kolor i ukształtowanie,
stan komponentu.
Rysunek 12. Przycisk z: enabled = true
(po lewej) i enabled = false
(po prawej).
W większości przypadków można polegać na wartościach domyślnych w przypadku takich wartości jak kolor i wysokość. Jeśli chcesz skonfigurować wartości używane w różnych stanach, dostępne są klasy i ułatwienia dostępu. Zobacz przykładowy przycisk poniżej:
Button( onClick = { /* ... */ }, enabled = true, // Custom colors for different states colors = ButtonDefaults.buttonColors( backgroundColor = MaterialTheme.colors.secondary, disabledBackgroundColor = MaterialTheme.colors.onBackground .copy(alpha = 0.2f) .compositeOver(MaterialTheme.colors.background) // Also contentColor and disabledContentColor ), // Custom elevation for different states elevation = ButtonDefaults.elevation( defaultElevation = 8.dp, disabledElevation = 2.dp, // Also pressedElevation ) ) { /* ... */ }
Rysunek 13. Przycisk z: enabled = true
(po lewej) i enabled = false
(po prawej) z dostosowanymi kolorami i wartościami wysokości.
Kręgi na wodzie
Komponenty materiałowe wykorzystują fale, które wskazują, że wchodzą w interakcję z nimi. Jeśli
używasz w hierarchii funkcji MaterialTheme
, Ripple
zostanie użyty jako
domyślny Indication
wewnętrzne modyfikatory, takie jak
clickable
i
indication
W większości przypadków możesz polegać na domyślnym Ripple
. Konfiguracja
ich wyglądu,
RippleTheme
aby zmienić właściwości, takie jak kolor i alfa.
Możesz przedłużyć czas korzystania z usługi RippleTheme
i korzystać z
defaultRippleColor
i
defaultRippleAlpha
funkcji użytkowych. Możesz następnie podać własny motyw Echo w swojej hierarchii za pomocą
LocalRippleTheme
:
@Composable fun MyApp() { MaterialTheme { CompositionLocalProvider( LocalRippleTheme provides SecondaryRippleTheme ) { // App content } } } @Immutable private object SecondaryRippleTheme : RippleTheme { @Composable override fun defaultColor() = RippleTheme.defaultRippleColor( contentColor = MaterialTheme.colors.secondary, lightTheme = MaterialTheme.colors.isLight ) @Composable override fun rippleAlpha() = RippleTheme.defaultRippleAlpha( contentColor = MaterialTheme.colors.secondary, lightTheme = MaterialTheme.colors.isLight ) }
Rysunek 14. Przyciski z różnymi wartościami echa, dostarczane przez RippleTheme
.
Więcej informacji
Aby dowiedzieć się więcej o motywie Material Design w usłudze Compose, zapoznaj się z tymi artykułami z dodatkowymi zasobami.
Ćwiczenia z programowania
Filmy
.Polecane dla Ciebie
- Uwaga: tekst linku wyświetla się, gdy JavaScript jest wyłączony
- Niestandardowe systemy projektowania w Compose
- Migracja z Material 2 do Material 3 w usłudze Compose
- Ułatwienia dostępu w funkcji tworzenia wiadomości