Jetpack Compose bietet eine Implementierung von Material Design, einem umfassenden Designsystem für digitale Schnittstellen schaffen. Die Material Design-Komponenten (Schaltflächen, Karten, Schalter usw.) basieren auf Material Theming. Dies ist eine systematische Methode, Material Design so anzupassen, dass es die Marke Ihres Produkts besser widerspiegelt. Ein Material Das Design enthält die Attribute Farbe, Typografie und Form. Wenn Sie diese anpassen, -Attribute werden Ihre Änderungen automatisch in den von Ihnen verwendeten Komponenten um Ihre App zu entwickeln.
Jetpack Compose implementiert diese Konzepte mit der MaterialTheme
zusammensetzbar:
MaterialTheme( colors = // ... typography = // ... shapes = // ... ) { // app content }
Konfigurieren Sie die Parameter, die Sie an MaterialTheme
übergeben, um das Design Ihrer Anwendung festzulegen.
Abbildung 1. Der erste Screenshot zeigt eine App, die keine Konfiguration
MaterialTheme
. Daher wird der Standardstil verwendet. Der zweite Screenshot zeigt eine App, die Parameter an MaterialTheme
übergibt, um das Design anzupassen.
Farbe
Farben werden in Compose mit der Klasse Color
modelliert, einer einfachen Datenspeicherklasse.
val Red = Color(0xffff0000) val Blue = Color(red = 0f, green = 0f, blue = 1f)
Sie können diese beliebig organisieren (als Konstanten der obersten Ebene, Singleton-Format oder inline definiert, empfehlen wir dringend, Farben in Design ändern und die Farben von dort abrufen. So lassen sich dunkle Designs und verschachtelte Designs ganz einfach unterstützen.
Abbildung 2. Das Farbsystem „Material“.
Compose bietet die Klasse Colors
, um das Materialfarbsystem zu modellieren. Colors
bietet Builder-Funktionen zum Erstellen von Sets mit hellen oder dunklen Farben:
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, // ... )
Nachdem Sie Ihre Colors
definiert haben, können Sie sie an eine MaterialTheme
übergeben:
MaterialTheme( colors = if (darkTheme) DarkColors else LightColors ) { // app content }
Designfarben verwenden
Sie können die Colors
abrufen, die für die zusammensetzbare Funktion MaterialTheme
bereitgestellt wurde:
mit MaterialTheme.colors
.
Text( text = "Hello theming", color = MaterialTheme.colors.primary )
Oberflächen- und Inhaltsfarbe
Viele Komponenten akzeptieren ein Paar aus Farbe und Inhaltsfarbe:
Surface( color = MaterialTheme.colors.surface, contentColor = contentColorFor(color), // ... ) { /* ... */ } TopAppBar( backgroundColor = MaterialTheme.colors.primarySurface, contentColor = contentColorFor(backgroundColor), // ... ) { /* ... */ }
So können Sie nicht nur die Farbe eines Composeables festlegen, sondern auch eine Standardfarbe für den Inhalt, also die darin enthaltenen Composeables, angeben. Viele
Für zusammensetzbare Funktionen wird standardmäßig diese Inhaltsfarbe verwendet. Beispielsweise basiert die Farbe von Text
auf der Inhaltsfarbe des übergeordneten Elements und Icon
verwendet diese Farbe, um seine Tönung festzulegen.
Abbildung 3 Wenn Sie unterschiedliche Hintergrundfarben festlegen, werden unterschiedliche Text- und Symbolfarben verwendet.
Die contentColorFor()
den entsprechenden "on"-Wert
Farbe für alle Designfarben. Wenn Sie beispielsweise für Surface
die Hintergrundfarbe primary
festlegen, wird mit dieser Funktion onPrimary
als Inhaltsfarbe festgelegt. Wenn Sie eine Hintergrundfarbe festlegen, die kein Design ist, sollten Sie auch eine
die richtige Farbe für den Inhalt hat. LocalContentColor
verwenden
um die bevorzugte Inhaltsfarbe für den aktuellen Hintergrund abzurufen.
Position in der Hierarchie.
Alphaversion von Inhalten
Oft möchten Sie die Betonung von Inhalten variieren, um ihre Wichtigkeit zu vermitteln und eine visuelle Hierarchie zu schaffen. In den Empfehlungen für die Lesbarkeit von Text in Material Design wird empfohlen, unterschiedliche Opazitätsstufen zu verwenden, um unterschiedliche Wichtigkeitsstufen zu vermitteln.
Jetpack Compose implementiert dies über LocalContentAlpha
.
Sie können einen Alpha-Content für eine Hierarchie angeben, indem Sie einen Wert angeben.
für diese CompositionLocal
.
Verschachtelte Daten
zusammensetzbaren Funktionen können diesen Wert verwenden, um ihren Inhalt als Alpha zu behandeln.
Für Text
und Icon
wird beispielsweise standardmäßig die Kombination LocalContentColor
verwendet, die für die Verwendung von LocalContentAlpha
angepasst ist. Material gibt einige Standard-Alphawerte an (high
, medium
,
disabled
), die vom ContentAlpha
-Objekt modelliert werden.
// 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( // ... ) }
Weitere Informationen zu CompositionLocal
finden Sie unter Daten auf lokaler Ebene mit
CompositionLocal-Leitfaden.
Abbildung 4: Verschiedene Betonungsstufen auf Text anwenden, um visuell zu kommunizieren
Informationshierarchie gesprochen. Die erste Textzeile ist der Titel und enthält die wichtigsten Informationen. Daher wird hier ContentAlpha.high
verwendet. Die zweite Zeile enthält weniger wichtige Metadaten und verwendet daher ContentAlpha.medium
.
Dunkles Design
In Compose implementieren Sie helle und dunkle Designs, indem Sie dem MaterialTheme
-Komposit verschiedene Colors
-Elemente zur Verfügung stellen:
@Composable fun MyTheme( darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit ) { MaterialTheme( colors = if (darkTheme) DarkColors else LightColors, /*...*/ content = content ) }
In diesem Beispiel ist MaterialTheme
in einer eigenen zusammensetzbaren Funktion verpackt, die einen Parameter akzeptiert, der angibt, ob ein dunkles Design verwendet werden soll oder nicht. In
In diesem Fall erhält die Funktion den Standardwert für darkTheme
durch Abfrage der
Einstellung für das Gerätedesign.
Mit diesem Code können Sie prüfen, ob die aktuellen Colors
hell oder dunkel sind:
val isLightTheme = MaterialTheme.colors.isLight Icon( painterResource( id = if (isLightTheme) { R.drawable.ic_sun_24 } else { R.drawable.ic_moon_24 } ), contentDescription = "Theme" )
Höhen-Overlays
In Material werden Oberflächen in dunklen Designs mit höheren Elevation Höhen-Overlays, die um den Hintergrund aufzuhellen. Je höher die Höhe einer Oberfläche, also die Anhebung angedeutet, desto heller wird die Oberfläche.
Diese Overlays werden bei Verwendung der zusammensetzbaren Funktion Surface
automatisch angewendet,
sowie für alle anderen zusammensetzbaren Materialien, die eine Oberfläche verwenden, gehen Sie so vor:
Surface( elevation = 2.dp, color = MaterialTheme.colors.surface, // color will be adjusted for elevation /*...*/ ) { /*...*/ }
Abbildung 5: Sowohl die Karten als auch die untere Navigationsleiste haben die Farbe surface
als Hintergrund. Da sich die Karten und die untere Navigationsleiste auf unterschiedlichen Höhen über dem Hintergrund befinden, haben sie leicht unterschiedliche Farben: Die Karten sind heller als der Hintergrund und die untere Navigationsleiste ist heller als die Karten.
Für benutzerdefinierte Szenarien ohne Surface
verwenden Sie
LocalElevationOverlay
,
ein CompositionLocal
mit den
ElevationOverlay
verwendet von
Surface
Komponenten:
// 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 )
Um Höhen-Overlays zu deaktivieren, geben Sie null
an der gewünschten Stelle in einem
zusammensetzbare Hierarchie:
MyTheme { CompositionLocalProvider(LocalElevationOverlay provides null) { // Content without elevation overlays } }
Eingeschränkte Farbakzente
Material empfiehlt, begrenzte Farben anzuwenden
Akzente für dunkles
indem Sie die Farbe surface
gegenüber der Farbe primary
in
in den meisten Fällen. Material-Kompositionen wie TopAppBar
und BottomNavigation
implementieren dieses Verhalten standardmäßig.
Abbildung 6: Dunkles Materialdesign mit wenigen Farbakzenten. Obere App-Leiste Die Hauptfarbe wird im hellen Design und die Oberflächenfarbe im dunklen Design verwendet.
Verwenden Sie für benutzerdefinierte Szenarien das Erweiterungsattribut primarySurface
:
Surface( // Switches between primary in light theme and surface in dark theme color = MaterialTheme.colors.primarySurface, /*...*/ ) { /*...*/ }
Typografie
Material definiert einen Typ System, mit einigen semantisch benannten Stilen.
Abbildung 7. Das Materialtypsystem.
Compose implementiert das Typsystem mit den Klassen Typography
, TextStyle
und schriftarten. Der Typography
-Konstruktor bietet Standardwerte für jeden Stil. Sie können also alle Elemente weglassen, die Sie nicht anpassen möchten:
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, /*...*/) { /*...*/ }
Wenn Sie dieselbe Schriftart verwenden möchten, geben Sie defaultFontFamily parameter
an und lassen Sie die fontFamily
-Elemente aller TextStyle
-Elemente aus:
val typography = Typography(defaultFontFamily = raleway) MaterialTheme(typography = typography, /*...*/) { /*...*/ }
Textstile verwenden
Auf TextStyle
s kann über MaterialTheme.typography
zugegriffen werden. Rufen Sie die
Für TextStyle
gilt:
Text( text = "Subtitle2 styled", style = MaterialTheme.typography.subtitle2 )
Abbildung 8. Verwenden Sie eine Auswahl von Schriftarten und Stilen, um Ihre Marke zu präsentieren.
Form
Material definiert einen Formsystem können Sie um Formen für große, mittlere und kleine Komponenten zu definieren.
Abbildung 9: Das Materialformsystem.
In Compose wird das Formsystem mit der Klasse Shapes
implementiert. Damit können Sie für jede Größenkategorie eine CornerBasedShape
angeben:
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, /*...*/) { /*...*/ }
Viele Komponenten verwenden diese Formen standardmäßig. Beispiel:
Button
,
TextField
und
FloatingActionButton
auf „klein“ eingestellt,
AlertDialog
ist standardmäßig „Medium“ und
ModalDrawer
.
ist standardmäßig groß – siehe
Formschema-Referenz
für die vollständige Zuordnung.
Formen verwenden
Der Zugriff auf Shape
erfolgt über MaterialTheme.shapes
. Rufen Sie die Shape
s mit folgendem Code ab:
Surface( shape = MaterialTheme.shapes.medium, /*...*/ ) { /*...*/ }
Abbildung 10. Verwenden Sie Formen, um Marke oder Zustand zum Ausdruck zu bringen.
Standardstile
Es gibt kein äquivalentes Konzept in der Funktion zur Erstellung von Standardformate aus Android Views. Sie können ähnliche Funktionen bereitstellen, indem Sie eigene zusammensetzbare Funktionen erstellen, die Materialkomponenten umschließen. Um beispielsweise einen Schaltflächenstil zu erstellen, fassen Sie eine Schaltfläche in Ihrer eigenen zusammensetzbaren Funktion zusammen, legen Sie die zu ändernden Parameter direkt fest und stellen Sie andere als Parameter an die enthaltende zusammensetzbare Funktion zur Verfügung.
@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 ) }
Themen-Overlays
Sie können das Äquivalent zu Design-Overlays aus Android-Ansichten in Compose erzielen, indem Sie MaterialTheme
-Kompositionen verschachteln. Weil
In MaterialTheme
werden Farben, Typografie und Formen standardmäßig auf den aktuellen Designwert gesetzt. Wenn ein Design nur einen dieser Parameter festlegt, behalten die anderen Parameter ihre Standardwerte.
Wenn Sie auf Ansichten basierende Bildschirme zu Compose migrieren, achten Sie außerdem auf die Verwendung des Attributs android:theme
. Wahrscheinlich benötigen Sie in diesem Teil des Compose-UI-Baums eine neue MaterialTheme
.
In diesem Beispiel wird auf dem Detailbildschirm für den größten Teil des Bildschirms ein PinkTheme
und dann für den zugehörigen Bereich ein BlueTheme
verwendet. Siehe Screenshot und Code unten.
Abbildung 11. Verschachtelte Themen
@Composable fun DetailsScreen(/* ... */) { PinkTheme { // other content RelatedSection() } } @Composable fun RelatedSection(/* ... */) { BlueTheme { // content } }
Komponentenstatus
Materialkomponenten, mit denen interagiert werden kann (z. B. angeklickt oder ein-/ausgeschaltet werden), können sich in verschiedenen visuellen Status befinden. Zu den Status gehören „Aktiviert“, „Deaktiviert“, „Gedrückt“ usw.
Composables haben oft einen enabled
-Parameter. Wird sie auf false
gesetzt,
Interaktion und ändert Eigenschaften wie Farbe und Elevation, um
Komponentenstatus.
Abbildung 12. Schaltfläche mit enabled = true
(links) und enabled = false
(rechts)
In den meisten Fällen können Sie für Werte wie Farbe und Höhe die Standardeinstellungen verwenden. Wenn Sie Werte konfigurieren möchten, die in verschiedenen Status verwendet werden, gibt es Klassen und Komfortfunktionen verfügbar. Hier ein Beispiel für die Schaltfläche:
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 ) ) { /* ... */ }
Abbildung 13 Schaltfläche mit enabled = true
(links) und enabled = false
(rechts) mit angepassten Farb- und Höhenwerten.
Kreise im Wasser
Bei Materialkomponenten wird mit Wellen angezeigt, dass mit ihnen interagiert wird. Wenn
Sie MaterialTheme
in Ihrer Hierarchie verwenden, wird ein Ripple
als
StandardIndication
in Modifikatoren wie
clickable
und
indication
In den meisten Fällen können Sie den Standardwert Ripple
verwenden. Falls Sie das
Ihres Erscheinungsbilds, können Sie
RippleTheme
Eigenschaften wie Farbe und Alpha ändern.
Sie können RippleTheme
verlängern und die
defaultRippleColor
und
defaultRippleAlpha
Dienstprogrammfunktionen. Sie können dann Ihr benutzerdefiniertes Wellenthema in Ihrer Hierarchie mithilfe von
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 ) }
Abbildung 14: Schaltflächen mit unterschiedlichen Ripple-Werten, die über RippleTheme
bereitgestellt werden
Weitere Informationen
Weitere Informationen zu Material Theming in Compose findest du hier: zusätzliche Ressourcen.
Codelabs
Videos
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Benutzerdefinierte Designsysteme in Compose
- In Compose von Material 2 zu Material 3 migrieren
- Barrierefreiheit in der Google Compose-App