Material Design 2 w sekcji Utwórz

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.

Dwa kontrastujące zrzuty ekranu. pierwszy korzysta z domyślnego stylu MaterialTheme,
a drugi zrzut ekranu ma zmodyfikowany styl.

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.

Przykład palety kolorów motywu

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.

Dwa przykłady tego samego banera w różnych kolorach

Rysunek 3. Ustawienie różnych kolorów tła pozwala zmienić kolory 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.

Zrzut ekranu przedstawiający tytuł artykułu z różnymi poziomami tekstu
wyróżnienie

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
    /*...*/
) { /*...*/ }

Zrzut ekranu aplikacji przedstawiający subtelnie różne kolory elementów
na różnych poziomach wzniesienia

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.

Przykład kilku różnych krojów czcionek w różnych stylach

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
)

Zrzut ekranu pokazujący kombinację różnych krojów czcionek do różnych celów

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.

Pokazuje różne kształty w stylu Material Design.

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, /*...*/
) {
    /*...*/
}

Zrzut ekranu aplikacji, która używa kształtów Material Design do określania stanu elementu

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
    )
}

tekst_alternatywny

Rysunek 14. Przyciski z różnymi wartościami Echo z 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