Diese Seite bietet einen allgemeinen Überblick über die Architekturebenen, aus denen Jetpack Compose besteht, und die Grundprinzipien, die diesem Design zugrunde liegen.
Jetpack Compose ist kein einzelnes monolithisches Projekt. Es besteht aus mehreren Modulen, die zu einem vollständigen Stack zusammengefügt werden. Wenn Sie die verschiedenen Module von Jetpack Compose verstehen, können Sie:
- Geeignete Abstraktionsebene verwenden, um Ihre App oder Bibliothek zu erstellen
- Finden Sie heraus, wann Sie mit einem Drop-down-Menü auf eine niedrigere Ebene wechseln können, um mehr Kontrolle oder Anpassung zu haben.
- Abhängigkeiten minimieren
Ebenen
Die Hauptebenen von Jetpack Compose sind:
Abbildung 1: Die wichtigsten Ebenen von Jetpack Compose.
Jede Ebene baut auf den unteren Ebenen auf, wodurch verschiedene Funktionen kombiniert werden, um übergeordnete Komponenten zu erstellen. Jede Ebene baut auf öffentlichen APIs der unteren Ebenen auf, um die Modulgrenzen zu überprüfen und es Ihnen bei Bedarf zu ermöglichen, jede Ebene zu ersetzen. Untersuchen wir diese Ebenen von unten nach oben.
- Laufzeit
- In diesem Modul werden die Grundlagen der Compose-Laufzeit beschrieben, z. B.
remember
,mutableStateOf
, die Annotation@Composable
undSideEffect
. Sie können direkt auf dieser Ebene aufbauen, wenn Sie nur die Funktionen zur Baumverwaltung und nicht die UI von Composer benötigen. - Benutzeroberfläche
- Die UI-Ebene besteht aus mehreren Modulen (
ui-text
,ui-graphics
,ui-tooling
usw.). In diesen Modulen werden die Grundlagen des UI-Toolkits implementiert, z. B.LayoutNode
,Modifier
, Eingabe-Handler, benutzerdefinierte Layouts und Zeichnungen. Sie können auf dieser Ebene aufbauen, wenn Sie nur die grundlegenden Konzepte eines UI-Toolkits benötigen. - Grundlage
- Dieses Modul enthält Designsystem-unabhängige Bausteine für die Compose-UI, z. B.
Row
undColumn
,LazyColumn
, die Erkennung bestimmter Gesten usw. Sie können auf der Fundamentebene aufbauen, um Ihr eigenes Designsystem zu erstellen. - Material
- In diesem Modul wird eine Implementierung des Material Design-Systems für die Erstellungs-UI beschrieben. Dabei werden ein Designsystem, Komponenten mit benutzerdefinierten Stilen, Wellenangaben und Symbole bereitgestellt. Baue auf dieser Ebene auf, wenn du Material Design in deiner App verwendest.
Designprinzipien
Ein Leitprinzip für Jetpack Compose besteht darin, anstelle einiger monolithischer Komponenten kleine, fokussierte Funktionen bereitzustellen, die zusammen zusammengesetzt (oder zusammengesetzt) werden können. Dieser Ansatz bietet eine Reihe von Vorteilen.
Steuerung
Komponenten auf höherer Ebene leisten in der Regel mehr für Sie, schränken jedoch die direkte Kontrolle ein, die Sie haben. Wenn Sie mehr Kontrolle benötigen, können Sie das Drop-down-Menü verwenden, um eine Komponente auf einer niedrigeren Ebene zu verwenden.
Wenn Sie beispielsweise die Farbe einer Komponente animieren möchten, können Sie die animateColorAsState
API verwenden:
val color = animateColorAsState(if (condition) Color.Green else Color.Red)
Wenn die Komponente jedoch immer grau beginnen soll, ist dies mit dieser API nicht möglich. Stattdessen können Sie im Drop-down-Menü die untergeordnete API Animatable
verwenden:
val color = remember { Animatable(Color.Gray) } LaunchedEffect(condition) { color.animateTo(if (condition) Color.Green else Color.Red) }
Die übergeordnete animateColorAsState
API baut wiederum auf der niedrigeren Animatable
API auf. Die Verwendung der untergeordneten API ist komplexer, bietet aber mehr Kontrolle. Wählen Sie die Abstraktionsebene, die Ihren Anforderungen am besten entspricht.
Personalisierung
Das Zusammensetzen übergeordneter Komponenten aus kleineren Bausteinen macht es bei Bedarf wesentlich einfacher, Komponenten anzupassen. Hier ein Beispiel für die Implementierung von Button
, die durch die Material-Ebene bereitgestellt wird:
@Composable fun Button( // … content: @Composable RowScope.() -> Unit ) { Surface(/* … */) { CompositionLocalProvider(/* … */) { // set LocalContentAlpha ProvideTextStyle(MaterialTheme.typography.button) { Row( // … content = content ) } } } }
Ein Button
besteht aus vier Komponenten:
Ein Material
Surface
, das Hintergrund, Form, Klickbehandlung usw. bereitstellt.Ein
CompositionLocalProvider
-Element, das den Alphawert des Inhalts ändert, wenn die Schaltfläche aktiviert oder deaktiviert istMit
ProvideTextStyle
wird der zu verwendende Standardtextstil festgelegt.Ein
Row
stellt die Standardlayoutrichtlinie für den Inhalt der Schaltfläche bereit
Wir haben einige Parameter und Kommentare weggelassen, um die Struktur klarer zu gestalten. Die gesamte Komponente besteht jedoch nur aus etwa 40 Codezeilen, da sie einfach diese vier Komponenten zur Implementierung der Schaltfläche zusammensetzt. Bei Komponenten wie Button
wird berücksichtigt, welche Parameter verfügbar gemacht werden. So lassen sich allgemeine Anpassungen vermeiden, da die Parameter oft verwendet werden, die eine Komponente erschweren. Material-Komponenten bieten beispielsweise im Material-Design-System spezifizierte Anpassungen, die die Einhaltung der Material-Design-Prinzipien erleichtern.
Wenn Sie jedoch eine Anpassung vornehmen möchten, die über die Parameter einer Komponente hinausgeht, können Sie eine Ebene auf „Dropdown“ setzen und eine Komponente abspalten. Zum Beispiel gibt Material Design an, dass Schaltflächen einen einfarbigen Hintergrund haben sollen. Wenn Sie einen Farbverlaufshintergrund benötigen, wird diese Option von den Button
-Parametern nicht unterstützt. In diesem Fall kannst du die Material-Implementierung Button
als Referenz verwenden und deine eigene Komponente erstellen:
@Composable fun GradientButton( // … background: List<Color>, modifier: Modifier = Modifier, content: @Composable RowScope.() -> Unit ) { Row( // … modifier = modifier .clickable(onClick = {}) .background( Brush.horizontalGradient(background) ) ) { CompositionLocalProvider(/* … */) { // set material LocalContentAlpha ProvideTextStyle(MaterialTheme.typography.button) { content() } } } }
Für die obige Implementierung werden weiterhin Komponenten aus der Material-Ebene verwendet, z. B. die Konzepte von Material für das aktuelle Inhalts-Alpha und den aktuellen Textstil. Allerdings wird das Material Surface
durch ein Row
ersetzt und es so formatiert, dass es das gewünschte Erscheinungsbild erreicht.
Wenn Sie Material-Konzepte überhaupt nicht verwenden möchten, z. B. wenn Sie Ihr eigenes maßgeschneidertes Designsystem erstellen, können Sie auf die ausschließliche Verwendung von Fundament-Layer-Komponenten umsteigen:
@Composable fun BespokeButton( // … backgroundColor: Color, modifier: Modifier = Modifier, content: @Composable RowScope.() -> Unit ) { Row( // … modifier = modifier .clickable(onClick = {}) .background(backgroundColor) ) { // No Material components used content() } }
Jetpack Compose reserviert die einfachsten Namen für die Komponenten der höchsten Ebene. Beispielsweise basiert androidx.compose.material.Text
auf androidx.compose.foundation.text.BasicText
.
Wenn Sie höhere Ebenen ersetzen möchten, können Sie auf diese Weise Ihre eigene Implementierung mit dem am besten auffindbaren Namen verwenden.
Die richtige Abstraktion auswählen
Die Philosophie von Compose zum Erstellen von mehrschichtigen, wiederverwendbaren Komponenten bedeutet, dass Sie nicht immer nach den Bausteinen der unteren Ebenen greifen sollten. Viele Komponenten auf höherer Ebene bieten nicht nur mehr Funktionen, sondern implementieren häufig Best Practices wie die Unterstützung der Barrierefreiheit.
Wenn Sie beispielsweise Ihrer benutzerdefinierten Komponente die Unterstützung von Touch-Gesten hinzufügen möchten, können Sie dies mit Modifier.pointerInput
von Grund auf neu erstellen. Es gibt aber auch andere übergeordnete Komponenten, die einen besseren Ausgangspunkt bieten, z. B. Modifier.draggable
, Modifier.scrollable
oder Modifier.swipeable
.
In der Regel sollten Sie auf der Komponente der höchsten Ebene aufbauen, die die Funktionen bietet, die Sie benötigen, um von den darin enthaltenen Best Practices zu profitieren.
Weitere Informationen
Im Jetsnack-Beispiel finden Sie ein Beispiel für das Erstellen eines benutzerdefinierten Designsystems.
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Kotlin für Jetpack Compose
- Listen und Raster
- Nebeneffekte in der Funktion „Schreiben“