Grundlagen von Stilen

Es gibt drei Möglichkeiten, Stile in Ihrer App zu verwenden:

  1. Direkt auf vorhandene Komponenten anwenden, die einen Style Parameter haben.
  2. Einen Stil mit Modifier.styleable auf Layout Composables anwenden, die keinen Style Parameter akzeptieren.
  3. In Ihrem eigenen benutzerdefinierten Designsystem Modifier.styleable{} verwenden und einen Stilparameter für Ihre eigenen Komponenten bereitstellen.

Verfügbare Attribute für Stile

Stile unterstützen viele der gleichen Attribute wie Modifikatoren. Allerdings kann nicht alles, was ein Modifikator ist, mit einem Stil repliziert werden. Für bestimmte Verhaltensweisen wie Interaktionen, benutzerdefinierte Zeichnungen oder das Stapeln von Attributen sind weiterhin Modifikatoren erforderlich.

Gruppierung Attribute Von untergeordneten Elementen übernommen
Layout und Größe
Content Padding (innen) - contentPadding(all: Dp)
- contentPadding(horizontal: Dp, vertical: Dp)
- contentPadding(start: Dp, top: Dp, end: Dp, bottom: Dp)
- contentPaddingHorizontal(value: Dp) / contentPaddingVertical(value: Dp)
- contentPaddingStart(value: Dp) / contentPaddingTop(value: Dp) / contentPaddingEnd(value: Dp) / contentPaddingBottom(value: Dp)
Nein
External Padding (außen) - externalPadding(all: Dp)
- externalPadding(horizontal: Dp, vertical: Dp)
- externalPadding(start: Dp, top: Dp, end: Dp, bottom: Dp)
- externalPaddingHorizontal(value: Dp) / externalPaddingVertical(value: Dp)
- externalPaddingStart(value: Dp) / externalPaddingTop(value: Dp) / externalPaddingEnd(value: Dp) / externalPaddingBottom(value: Dp)
Nein
Abmessungen fillWidth()/fillHeight()/fillSize() und width, height und size (unterstützt Dp, DpSize oder Float Brüche). Nein
Positionierung left/top/right/bottom-Offsets. Nein
Visuelles Erscheinungsbild
Füllen background und foreground (unterstützt Color oder Brush). Nein
Rahmen borderWidth, borderColor und borderBrush. Nein
Form shape Nein, wird aber in Verbindung mit anderen Attributen verwendet. clip und border verwenden diese definierte Form.
Schatten dropShadow, innerShadow Nein
Transformationen
Räumliche Bewegung der Grafikebene translationX, translationY, scaleX/scaleY, rotationX/rotationY/rotationZ Nein
Steuerung alpha, zIndex (Stapelreihenfolge) und transformOrigin (Drehpunkt) Nein
Typografie
Stil textStyle, fontSize, fontWeight, fontStyle und fontFamily Ja
Farbe contentColor und contentBrush. Wird auch für das Design von Symbolen verwendet. Ja
Absatz lineHeight, letterSpacing, textAlign, textDirection, lineBreak und hyphens. Ja
Dekoration textDecoration, textIndent und baselineShift. Ja

Stile direkt auf Komponenten mit Stilparametern anwenden

Bei Komponenten, die einen Style-Parameter haben, können Sie das Design festlegen:

BaseButton(
    onClick = { },
    style = { }
) {
    BaseText("Click mnippets.kt

In der Stil-Lambda können Sie verschiedene Attribute festlegen, z. B. externalPadding oder background:

BaseButton(
    onClick = { },
    style = { background(Color.Blue) }
) {
    BaseText("Click mnippets.kt

Die vollständige Liste der unterstützten Attribute finden Sie unter Verfügbare Attribute für Stile.

Stile mit Modifikatoren auf Komponenten ohne vorhandenen Parameter anwenden

Für Komponenten ohne integrierten Stilparameter können Sie trotzdem Stile mit dem Modifikator styleable anwenden. Dieser Ansatz ist auch nützlich, wenn Sie eigene benutzerdefinierte Komponenten entwickeln.

Row(
    modifier = Modifier.styleable { }
) {
    BaseText("Contennippets.kt

Ähnlich wie beim Parameter style können Sie Attribute wie background, contentPadding oder externalPadding in die Lambda einfügen.

Row(
    modifier = Modifier.styleable {
        background(Color.Blue)
    }
) {
    BaseText("Contennippets.kt

Mehrere verkettete Modifier.styleable-Modifikatoren sind additiv mit nicht übernommenen Attributen für das angewendete Composable und verhalten sich ähnlich wie mehrere Modifikatoren, die dieselben Attribute definieren. Bei übernommenen Attributen werden diese überschrieben und der letzte styleable-Modifikator in der Kette legt die Werte fest.

Wenn Sie Modifier.styleable verwenden, sollten Sie auch einen StyleState erstellen und bereitstellen, der mit dem Modifikator verwendet wird, um zustandsbasiertes Design anzuwenden. Weitere Informationen finden Sie unter Zustand und Animationen mit Stilen.

Eigenständigen Stil definieren

Sie können einen eigenständigen Stil definieren, um ihn wiederzuverwenden:

val style = Style { background(Color.Blue) }

Sie können diesen definierten Stil dann an den Stilparameter eines Composables oder mit Modifier.styleable übergeben. Wenn Sie Modifier.styleable verwenden, müssen Sie auch ein StyleState-Objekt erstellen. StyleState wird ausführlich in der Zustand und Animationen mit Stilen Dokumentation behandelt.

Im folgenden Beispiel wird gezeigt, wie Sie einen Stil entweder direkt über die integrierten Parameter einer Komponente oder über einen Modifier.styleable anwenden können:

val style = Style { background(Color.Blue) }

// built in parameter
BaseButton(onClick = { }, style = style) {
    BaseText("Button")
}

// modifier styleable
val styleState = remember { MutableStyleState(null) }
Column(
    Modifier.styleable(styleState, style)
) {
    BaseText("Col)
}StylesSnippets.kt

Sie können diesen Stil auch an mehrere Komponenten übergeben:

val style = Style { background(Color.Blue) }

// built in parameter
BaseButton(onClick = { }, style = style) {
    BaseText("Button")
}
BaseText("Different text that uses the same style parameter", style = style)

// modifier styleable
val columnStyleState = remember { MutableStyleState(null) }
Column(
    Modifier.styleable(columnStyleState, style)
) {
    BaseText("Column")
}
val rowStyleState = remember { MutableStyleState(null) }
Row(
    Modifier.styleable(rowStyleState, stText("Row")
}StylesSnippets.kt

Mehrere Stileigenschaften hinzufügen

Sie können mehrere Stileigenschaften hinzufügen, indem Sie in jeder Zeile unterschiedliche Eigenschaften festlegen:

BaseButton(
    onClick = { },
    style = {
        background(Color.Blue)
        contentPaddingStart(16.dp)
    }
) {
    BaseText("Buttonippets.kt

Attribute in Stilen sind nicht additiv, anders als beim modifikatorbasierten Design. Stile verwenden den zuletzt festgelegten Wert in der Liste der Attribute innerhalb eines Stilblocks. Im folgenden Beispiel wird die Hintergrundfarbe zweimal festgelegt. TealColor ist die angewendete Hintergrundfarbe. Bei der Auffüllung überschreibt contentPaddingTop die obere Auffüllung, die mit contentPadding festgelegt wurde, und kombiniert die Werte nicht.

BaseButton(
    style = {
        background(Color.Red)
        // Background of Red is now overridden with TealColor instead
        background(TealColor)
        // All directions of padding are set to 64.dp (top, start, end, bottom)
        contentPadding(64.dp)
        // Top padding is now set to 16.dp, all other paddings remain at 64.dp
        contentPaddingTop(16.dp)
    },
    onClick = {
        //
    }
) {
    BaseText("Click menippets.kt

Button mit zwei festgelegten Hintergrundfarben und zwei Überschreibungen für „contentPadding“
Abbildung 1. Schaltfläche mit zwei festgelegten Hintergrundfarben und zwei contentPadding-Überschreibungen.

Mehrere Stilobjekte zusammenführen

Sie können mehrere Stilobjekte erstellen und sie an den Stilparameter Ihres Composables übergeben.

val style1 = Style { background(TealColor) }
val style2 = Style { contentPaddingTop(16.dp) }

BaseButton(
    style = style1 then style2,
    onClick = {

    },
) {
    BaseText("Click menippets.kt

Schaltfläche mit Hintergrundfarbe und „contentPaddingTop“ festgelegt
Abbildung 2. Schaltfläche mit festgelegter Hintergrundfarbe und contentPaddingTop.

Wenn mehrere Stile dasselbe Attribut angeben, wird das zuletzt festgelegte Attribut ausgewählt. Da Attribute in Stilen nicht additiv sind, überschreibt die zuletzt übergebene Auffüllung die contentPaddingHorizontal mit dem ursprünglichen contentPadding festgelegte. Außerdem überschreibt die letzte Hintergrundfarbe die Hintergrundfarbe, die mit dem ursprünglich übergebenen Stil festgelegt wurde.

val style1 = Style {
    background(Color.Red)
    contentPadding(32.dp)
}

val style2 = Style {
    contentPaddingHorizontal(8.dp)
    background(Color.LightGray)
}

BaseButton(
    style = style1 then style2,
    onClick = {

    },
) {
    BaseText("Click menippets.kt

In diesem Fall hat das angewendete Design einen hellgrauen Hintergrund und eine Auffüllung von 32.dp, mit Ausnahme der linken und rechten Auffüllung, die einen Wert von 8.dp hat.

Schaltfläche mit „contentPadding“, das durch verschiedene Stile überschrieben wird
Abbildung 3. Schaltfläche mit contentPadding, die von verschiedenen Stilen überschrieben wird.

Stilübernahme

Bestimmte Stileigenschaften wie contentColor und textstilbezogene Eigenschaften werden an die untergeordneten Composables weitergegeben. Ein Stil, der für ein untergeordnetes Composable festgelegt wurde, überschreibt das übernommene übergeordnete Design für dieses bestimmte untergeordnete Element.

Stilübertragung mit den Parametern „style“, „styleable“ und „direct“
Abbildung 4. Stilweitergabe mit Style, styleable und direkten Parametern.
Priorität Methode Effekt
1 (höchste Priorität) Direkte Argumente für ein Composable Überschreibt alles, z. B. Text(color = Color.Red)
2 Stilparameter Lokale Stilüberschreibungen Text(style = Style { contentColor(Color.Red)}
3 Modifikatorkette Modifier.styleable{ contentColor(Color.Red) für die Komponente selbst.
4 (niedrigste Priorität) Übergeordnete Stile Für Attribute, die übernommen werden können (Typografie/Farbe), die vom übergeordneten Element weitergegeben werden.

Übergeordnetes Design

Sie können Texteigenschaften (z. B. contentColor) aus dem übergeordneten Composable festlegen. Sie werden an alle untergeordneten Text-Composables weitergegeben.

val styleState = remember { MutableStyleState(null) }
Column(
    modifier = Modifier.styleable(styleState) {
        background(Color.LightGray)
        val blue = Color(0xFF4285F4)
        val purple = Color(0xFFA250EA)
        val colors = listOf(blue, purple)
        contentBrush(Brush.linearGradient(colors))
    },
) {
    BaseText("Children inherit", style = { width(60.dp) })
    BaseText("certain properties")
    BaseText(&quents")
}StylesSnippets.kt

Übernahme von Eigenschaften untergeordneter Composables
Abbildung 5. Attributübernahme von untergeordneten Composables.

Untergeordnete Überschreibung von Attributen

Sie können auch das Design für ein bestimmtes Text-Composable festlegen. Wenn für das übergeordnete Composable ein Design festgelegt ist, überschreibt das für das untergeordnete Composable festgelegte Design das Design des übergeordneten Composables.

val styleState = remember { MutableStyleState(null) }
Column(
    modifier = Modifier.styleable(styleState) {
        background(Color.LightGray)
        val blue = Color(0xFF4285F4)
        val purple = Color(0xFFA250EA)
        val colors = listOf(blue, purple)
        contentBrush(Brush.linearGradient(colors))
    },
) {
    BaseText("Children can ", style = {
        contentBrush(Brush.linearGradient(listOf(Color.Red, Color.Blue)))
    })
    BaseText("override properties")
    BaseText("ents")
}StylesSnippets.kt

Untergeordnete Composables überschreiben übergeordnete Eigenschaften
Abbildung 6. Untergeordnete Composables überschreiben übergeordnete Attribute.

Benutzerdefinierte Stileigenschaften implementieren

Sie können benutzerdefinierte Attribute erstellen, die vorhandenen Stildefinitionen zugeordnet werden, indem Sie Erweiterungsfunktionen für StyleScope verwenden, wie im folgenden Beispiel gezeigt:

fun StyleScope.outlinedBackground(color: Color) {
    border(1.dp, color)
    background(color)
}

Wenden Sie dieses neue Attribut in einer Stildefinition an:

val customExtensionStyle = Style {
    outlinedBackground(Color.Blue)
}

Das Erstellen neuer styleable-Attribute wird nicht unterstützt. Wenn Sie diese Unterstützung benötigen, senden Sie einen Feature Request.

CompositionLocal-Werte lesen

Es ist ein gängiges Muster, Designsystem-Tokens in einem CompositionLocal zu speichern, um auf die Variablen zuzugreifen, ohne sie als Parameter übergeben zu müssen. Stile können auf CompositionLocals zugreifen, um systemweite Werte in einem Stil abzurufen:

val buttonStyle = Style {
    contentPadding(12.dp)
    shape(RoundedCornerShape(50))
    background(Brush.verticalGradient(LocalCustomColors.currentValue.background))
}