Erste Schritte mit Kacheln


Wenn du Kacheln aus deiner App bereitstellen möchtest, füge die folgenden Abhängigkeiten in die build.gradle-Datei deiner App ein.

Cool

dependencies {
    // Use to implement support for wear tiles
    implementation "androidx.wear.tiles:tiles:1.6.2"

    // Use to utilize standard components and layouts in your tiles
    implementation "androidx.wear.protolayout:protolayout:1.4.2"

    // Use to utilize components and layouts with Material Design in your tiles
    implementation "androidx.wear.protolayout:protolayout-material:1.4.2"

    // Use to include dynamic expressions in your tiles
    implementation "androidx.wear.protolayout:protolayout-expression:1.4.2"

    // Use to preview wear tiles in your own app
    debugImplementation "androidx.wear.tiles:tiles-renderer:1.6.2"

    // Use to fetch tiles from a tile provider in your tests
    testImplementation "androidx.wear.tiles:tiles-testing:1.6.2"
}

Kotlin

dependencies {
    // Use to implement support for wear tiles
    implementation("androidx.wear.tiles:tiles:1.6.2")

    // Use to utilize standard components and layouts in your tiles
    implementation("androidx.wear.protolayout:protolayout:1.4.2")

    // Use to utilize components and layouts with Material Design in your tiles
    implementation("androidx.wear.protolayout:protolayout-material:1.4.2")

    // Use to include dynamic expressions in your tiles
    implementation("androidx.wear.protolayout:protolayout-expression:1.4.2")

    // Use to preview wear tiles in your own app
    debugImplementation("androidx.wear.tiles:tiles-renderer:1.6.2")

    // Use to fetch tiles from a tile provider in your tests
    testImplementation("androidx.wear.tiles:tiles-testing:1.6.2")
}

Wichtige Konzepte

Kacheln werden nicht auf dieselbe Weise wie Android-Apps erstellt und verwenden andere Konzepte:

  • Layoutvorlagen: Definieren die allgemeine Anordnung der visuellen Elemente auf dem Display. Dies wird durch die Funktion primaryLayout() erreicht.
  • Layoutelemente: Stellen ein einzelnes grafisches Element dar, z. B. einen Button oder eine Karte, oder mehrere solcher Elemente, die mithilfe einer Spalte, einer buttonGroup oder Ähnlichem gruppiert sind. Diese sind in eine Layoutvorlage eingebettet.
  • Ressourcen: ResourceBuilders.Resources-Objekte bestehen aus einer Zuordnung von Schlüssel/Wert-Paaren der Android-Ressourcen (Bilder), die zum Rendern eines Layouts erforderlich sind, und einer Version.
  • Zeitachse: Ein TimelineBuilders.Timeline-Objekt ist eine Liste mit einer oder mehreren Instanzen eines Layoutobjekts. Sie können verschiedene Mechanismen und Ausdrücke angeben, um festzulegen, wann der Renderer von einem Layoutobjekt zu einem anderen wechseln soll, z. B. um die Anzeige eines Layouts zu einem bestimmten Zeitpunkt zu beenden.
  • Status: Eine Datenstruktur vom Typ StateBuilders.State, die zwischen Kachel und App übergeben wird, damit die beiden Komponenten miteinander kommunizieren können. Wenn beispielsweise auf eine Schaltfläche auf der Kachel getippt wird, enthält der Status die ID der Schaltfläche. Sie können Datentypen auch mithilfe einer Zuordnung austauschen.
  • Kachel: Ein TileBuilders.Tile-Objekt, das eine Kachel darstellt und aus einer Zeitachse, einer Ressourcenversions-ID, einem Aktualisierungsintervall und einem Status besteht.
  • Protolayout: Dieser Begriff wird im Namen verschiedener Klassen verwendet, die mit Kacheln zusammenhängen, und bezieht sich auf die Wear OS Protolayout-Bibliothek, eine Grafikbibliothek, die auf verschiedenen Wear OS-Oberflächen verwendet wird.

Kachel erstellen

Material3TileService verwenden (empfohlen)

Wenn du Material 3-Tiles (androidx.wear.tiles:tiles:1.6.0 und höher) erstellst, erweitere immer Material3TileService anstelle der untergeordneten Klasse TileService. Material3TileService bietet eine auf Kotlin ausgerichtete Architektur, die die Entwicklung von Kacheln vereinfacht:

  • Integrierte Kotlin-Koroutinen: Implementieren Sie eine einzelne aussetzende MaterialScope.tileResponse(requestParams: TileRequest): Tile-Funktion, anstatt ListenableFuture zu verwenden und onTileRequest() zu überschreiben.
  • Vorkonfigurierter MaterialScope: tileResponse() wird mit MaterialScope als Empfänger ausgeführt (konfiguriert über Konstruktorparameter wie allowDynamicTheme und defaultColorScheme). Sie müssen Ihr Layout also nicht in einen redundanten materialScope()-Aufruf einbinden.
  • Ressourcenregistrierung mit einem einzigen Aufruf: Enthält ProtoLayoutScope, um Inline-Bildressourcen automatisch zu registrieren und sowohl das Kachellayout als auch die Ressourcen in einem einzigen Systembinderaufruf zurückzugeben. Da Material3TileService Ressourcen automatisch verarbeitet (final onTileResourcesRequest()), sollten Sie onTileResourcesRequest() nicht überschreiben.
class MyTileService : Material3TileService() {

    override suspend fun MaterialScope.tileResponse(requestParams: TileRequest): Tile =
        tile(
            timeline =
            Timeline.fromLayoutElement(
                primaryLayout(
                    mainSlot = {
                        text("Hello, World!".layoutString, typography = BODY_LARGE)
                    }
                )
            )
        )
}

Zugrunde liegende TileService-Architektur

Material3TileService baut auf der Basisklasse TileService auf, die in den übrigen Beispielen in diesem Leitfaden zur Veranschaulichung von Low-Level-Konzepten verwendet wird.

Wenn du eine Kachel aus deiner App bereitstellen möchtest, implementiere einen Dienst vom Typ TileService und registriere ihn in deinem Manifest. Daraus fordert das System die erforderlichen Kacheln bei Aufrufen von onTileRequest() und die Ressourcen bei Aufrufen von onTileResourcesRequest() an.

class MyTileService : TileService() {

    override fun onTileRequest(requestParams: RequestBuilders.TileRequest) =
        Futures.immediateFuture(
            Tile.Builder()
                .setResourcesVersion(RESOURCES_VERSION)
                .setTileTimeline(
                    Timeline.fromLayoutElement(
                        materialScope(this, requestParams.deviceConfiguration) {
                            primaryLayout(
                                mainSlot = {
                                    text("Hello, World!".layoutString, typography = BODY_LARGE)
                                }
                            )
                        }
                    )
                )
                .build()
        )

    override fun onTileResourcesRequest(requestParams: ResourcesRequest) =
        Futures.immediateFuture(Resources.Builder().setVersion(RESOURCES_VERSION).build())
}

Fügen Sie als Nächstes einen Dienst im <application>-Tag Ihrer AndroidManifest.xml-Datei hinzu.

<service
    android:name=".snippets.m3.tile.MyTileService"
    android:label="@string/tile_label"
    android:description="@string/tile_description"
    android:icon="@mipmap/ic_launcher"
    android:exported="true"
    android:permission="com.google.android.wearable.permission.BIND_TILE_PROVIDER">
    <intent-filter>
        <action android:name="androidx.wear.tiles.action.BIND_TILE_PROVIDER" />
    </intent-filter>

    <meta-data android:name="androidx.wear.tiles.PREVIEW"
        android:resource="@drawable/tile_preview" />
</service>

Durch die Berechtigung und den Intent-Filter wird dieser Dienst als TileProvider registriert.

Das Symbol, das Label, die Beschreibung und die Vorschauressource werden dem Nutzer angezeigt, wenn er Kacheln auf seinem Smartphone oder seiner Smartwatch konfiguriert. Die Vorschauressource unterstützt alle Standard-Ressourcenqualifizierer von Android. Daher kann die Vorschau je nach Faktoren wie Bildschirmgröße und Gerätesprache variieren. Weitere Empfehlungen finden Sie in der Checkliste für die Vorschau.

Stelle deine App bereit und füge die Kachel dem Kachelkarussell hinzu. Es gibt auch eine entwicklerfreundlichere Möglichkeit, eine Vorschau einer Kachel anzuzeigen, aber für den Moment kannst du es einfach manuell machen.

Eine mit Material 3 erstellte Wear OS-Tile mit dem Text „Hello World“.
Abbildung 1. „Hello World“-Tile.

Ein vollständiges Beispiel finden Sie im Codebeispiel auf GitHub oder im Codelab.

Benutzeroberfläche für Kacheln erstellen

Die ausdrucksstarken UI-Elemente von Material 3 Expressive werden mit einem strukturierten Ansatz erstellt, der auf dem typsicheren Builder-Muster von Kotlin basiert.

Layout

Informationen zu den Designprinzipien für effektive und responsive Kachellayouts finden Sie unter Häufige Layouts für Kacheln.

So erstellen Sie ein Layout:

  1. Material Design-Bereich initiieren: Rufen Sie die Funktion materialScope() auf und geben Sie die erforderlichen context und deviceConfiguration an. Sie können optionale Parameter wie allowDynamicTheme und defaultColorScheme angeben. allowDynamicTheme ist standardmäßig true und defaultColorScheme steht für die ColorScheme, die verwendet wird, wenn dynamische Farben nicht verfügbar sind, z. B. wenn der Nutzer die Funktion deaktiviert hat, wenn sie vom Gerät nicht unterstützt wird oder wenn allowDynamicTheme false ist. Wenn du ImageResource-APIs wie backgroundImage() in einem benutzerdefinierten TileService verwendest, rufe stattdessen materialScopeWithResources() auf.

  2. UI im Bereich erstellen: Alle UI-Komponenten für ein bestimmtes Kachellayout müssen innerhalb des Lambda-Ausdrucks eines einzelnen materialScope()-Aufrufs auf oberster Ebene definiert werden. Diese Komponentenfunktionen wie primaryLayout() und textEdgeButton() sind Erweiterungsfunktionen für MaterialScope und nur verfügbar, wenn sie in diesem Empfängerbereich aufgerufen werden.

    materialScope(
        context = context,
        deviceConfiguration =
        requestParams.deviceConfiguration, // requestParams is passed to onTileRequest
        defaultColorScheme = myFallbackColorScheme
    ) {
        // inside the MaterialScope, you can call functions like primaryLayout()
        primaryLayout(
            titleSlot = { text(text = "Title".layoutString) },
            mainSlot = { text(text = "Main Content".layoutString) },
            bottomSlot = {
                textEdgeButton(
                    labelContent = { text("Action".layoutString) },
                    onClick = clickable()
                )
            }
        )
    }

Slots

In M3 wird für das Kachellayout ein von Compose inspirierter Ansatz verwendet, bei dem drei verschiedene Slots zum Einsatz kommen. Von oben nach unten sind das:

  1. titleSlot, normalerweise für einen Haupttitel oder eine Überschrift.
  2. mainSlot für den Hauptinhalt.
  3. Die bottomSlot, die häufig für Aktionen oder zusätzliche Informationen verwendet wird. Hier wird auch ein Edge-Button angezeigt.
Kachellayout mit titleSlot, mainSlot und bottomSlot
Abbildung 2: titleSlot, mainSlot und bottomSlot.

Der Inhalt der einzelnen Slots ist folgender:

  • titleSlot (optional): In der Regel ein paar Wörter, die von text() generiert werden.
  • mainSlot (obligatorisch): Komponenten, die in Strukturen wie Zeilen, Spalten und Schaltflächengruppen organisiert sind. Diese Komponenten können auch rekursiv ineinander eingebettet werden. Eine Spalte kann beispielsweise Zeilen enthalten.
  • bottomSlot (optional): Wird in der Regel entweder mit einer Schaltfläche am Rand oder einem Textlabel gefüllt.

Da Kacheln nicht gescrollt werden können, gibt es keine Komponenten für das Paging, Scrollen oder Verarbeiten langer Inhaltslisten. Achten Sie darauf, dass Inhalte sichtbar bleiben, wenn die Schriftgröße erhöht wird oder der Text aufgrund einer Übersetzung länger wird.

UI-Komponenten

Die protolayout-material3-Bibliothek bietet eine große Anzahl von Komponenten, die gemäß den Material 3 Expressive-Spezifikationen und Empfehlungen für die Benutzeroberfläche entwickelt wurden.

Tasten

Schaltflächen sind in erster Linie aktionsorientiert. Sie dienen dazu, bestimmte Aktionen auszulösen. Der Inhalt der einzelnen Schaltflächen, z. B. ein Symbol oder ein kurzer Text, gibt die Aktion an.

  • textButton(): Schaltfläche mit einem einzelnen Slot für (kurzen) Textinhalt
  • iconButton(): Schaltfläche mit einem einzelnen Slot für ein Symbol
  • avatarButton(): Pillenförmige Avatar-Schaltfläche mit bis zu drei Slots für Inhalte, die ein vertikal gestapeltes Label und ein sekundäres Label sowie ein Bild (Avatar) daneben darstellen
  • imageButton(): anklickbare Bildschaltfläche, die keine zusätzlichen Slots bietet, sondern nur ein Bild (z. B. backgroundImage als Hintergrund)
  • compactButton(): Kompakter Button mit bis zu zwei Slots für horizontal gestapelte Inhalte, die ein Symbol und daneben Text darstellen.
  • button(): Pillenförmige Schaltfläche mit bis zu drei Slots für Inhalte, die ein vertikal gestapeltes Label und ein sekundäres Label sowie ein Symbol daneben darstellen.

Edge-Tasten

Ein Edge-Button ist ein spezieller Button, der sich über die gesamte Breite erstreckt und am unteren Rand des runden Displays einer Smartwatch verankert ist. Er stellt die wichtigste Aktion dar, die auf dem aktuellen Kachelbildschirm ausgeführt werden kann.

  • iconEdgeButton(): Rand-Button mit einem einzelnen Slot für ein Symbol oder einen ähnlich runden, kleinen Inhalt
  • textEdgeButton(): Edge-Button mit einem einzelnen Slot für Text oder ähnlich lange und breite Inhalte

Karten

Karten sind in erster Linie informationsorientiert. Sie zeigen Sammlungen verwandter, strukturierter Daten an. Du kannst zwar interaktive Karten erstellen, aber in der Regel wird darauf eine Zusammenfassung von Informationen angezeigt, auf die der Nutzer dann tippen kann, um weitere Details zu sehen oder eine zugehörige Aktion auszuführen.

  • titleCard(): Titelkarte mit einem bis drei Slots, in der Regel textbasiert
  • appCard(): App-Karte mit bis zu fünf Slots, in der Regel textbasiert
  • textDataCard(): Datenkarte mit bis zu drei vertikal gestapelten Slots, die in der Regel text- oder zahlenbasiert sind
  • iconDataCard(): Datenkarte mit bis zu drei vertikal gestapelten Slots, die in der Regel text- oder zahlenbasiert sind, mit einem Symbol
  • graphicDataCard(): Grafikdatenkarte mit einem Slot für Grafikdaten, z. B. eine Fortschrittsanzeige, und bis zu zwei vertikal gestapelten Slots, in der Regel für Textbeschreibungen

Fortschrittsanzeigen

Layoutelemente gruppieren

  • buttonGroup(): Komponentenlayout, bei dem die untergeordneten Elemente horizontal angeordnet werden
  • primaryLayout(): Vollbildlayout, das einen vorgeschlagenen responsiven M3-Layoutstil darstellt und die Platzierung der Elemente sowie die empfohlenen Ränder und Abstände berücksichtigt.

Design anwenden

In Material 3 Expressive wird das Farbsystem durch 29 Standardfarbrollen definiert, die in sechs Gruppen unterteilt sind: Primär, Sekundär, Tertiär, Fehler, Oberfläche und Umriss.

Das Material 3 Expressive Color System, in dem Farbrollen in Gruppen wie „Primär“, „Sekundär“, „Tertiär“, „Fehler“, „Oberfläche“ und „Umriss“ organisiert sind.
Abbildung 3: Das Farbsystem von Material 3 Expressive.

Ein ColorScheme ordnet jeder dieser 29 Rollen eine entsprechende Farbe zu. Da es Teil des MaterialScope ist und Komponenten darin erstellt werden müssen, übernehmen sie automatisch Farben aus dem Schema. So entsprechen alle UI-Elemente automatisch den Material Design-Standards.

Wenn du Nutzern die Möglichkeit geben möchtest, zwischen einem von dir definierten Farbschema (z. B. einem, das deine Markenfarben widerspiegelt) und einem vom System bereitgestellten Farbschema (entweder vom aktuellen Zifferblatt des Nutzers abgeleitet oder vom Nutzer ausgewählt) zu wählen, initialisiere MaterialScope so:

val myColorScheme =
    ColorScheme(
        primary = Color.rgb(0, 0, 255).argb, // Blue
        onPrimary = Color.rgb(255, 255, 255).argb, // White
        // 27 more
    )

materialScope(
    context = context,
    deviceConfiguration = requestParams.deviceConfiguration,
    defaultColorScheme = myColorScheme
) {
    // If the user selects "no theme" in settings, myColorScheme is used.
    // Otherwise, the system-provided theme is used.
}

Wenn du diese Option auswählst, musst du ein einfarbiges Kachelsymbol bereitstellen, damit es für eine optimale Sichtbarkeit vor jedem Design richtig eingefärbt werden kann.

Wenn Sie erzwingen möchten, dass Ihre Kacheln im von Ihnen angegebenen Farbschema angezeigt werden, deaktivieren Sie die Unterstützung für dynamische Designs, indem Sie allowDynamicTheme auf false setzen:

materialScope(
    context = context,
    deviceConfiguration = requestParams.deviceConfiguration,
    allowDynamicTheme = false,
    defaultColorScheme = myColorScheme
) {
    // myColorScheme is *always* used.
}

Farbe

Jede einzelne Komponente verwendet eine Teilmenge der 29 Farbenrollen, die durch ein ColorScheme definiert werden. Für Schaltflächen werden beispielsweise bis zu vier Farben verwendet, die standardmäßig aus der „primären“ Gruppe des aktiven ColorScheme stammen:

ButtonColors-Komponententoken Rolle ColorScheme
containerColor primär
iconColor onPrimary
labelColor onPrimary
secondaryLabelColor onPrimary (Deckkraft 0,8)

Eine ausführliche Anleitung zur Verwendung von Farben in Ihren Wear OS-Designs finden Sie im Leitfaden zum Farbdesign.

Möglicherweise müssen Sie für bestimmte UI-Elemente von den Standardfarb-Tokens abweichen. Beispielsweise möchten Sie vielleicht, dass eine textEdgeButton Farben aus der Gruppe „Sekundär“ oder „Tertiär“ anstelle von „Primär“ verwendet, um sich abzuheben und einen besseren Kontrast zu bieten.

Sie haben mehrere Möglichkeiten, die Farben von Komponenten anzupassen:

  1. Verwenden Sie eine Hilfsfunktion für vordefinierte Farben. Verwenden Sie Hilfsfunktionen wie filledTonalButtonColors(), um die Standard-Schaltflächenstile für Material 3 Expressive anzuwenden. Diese Funktionen erstellen vorkonfigurierte ButtonColors-Instanzen, die gängige Stile wie „filled“, „tonal“ oder „outlined“ den entsprechenden Rollen aus dem aktiven ColorScheme innerhalb des MaterialScope zuordnen. So können Sie einheitliche Stile anwenden, ohne jede Farbe für gängige Schaltflächentypen manuell definieren zu müssen.

    textEdgeButton(
        colors = filledButtonColors(), // default
        /* OR colors = filledTonalButtonColors() */
        /* OR colors = filledVariantButtonColors() */
        // ... other parameters
    )

    Verwenden Sie für Karten die entsprechende Funktionsfamilie filledCardColors().

    Sie können das von Hilfsfunktionen zurückgegebene ButtonColors-Objekt auch mit der Methode copy() ändern, wenn Sie nur ein oder zwei Tokens ändern müssen:

    textEdgeButton(
        colors =
        filledButtonColors()
            .copy(
                containerColor = colorScheme.tertiary,
                labelColor = colorScheme.onTertiary
            ),
        // ... other parameters
    )

  2. Geben Sie explizit Ersatzfarbrollen an. Erstellen Sie ein eigenes ButtonColors-Objekt und übergeben Sie es an die Komponente. Verwenden Sie für Karten das entsprechende CardColors-Objekt.

    textEdgeButton(
        colors =
        ButtonColors(
            // the materialScope makes colorScheme available
            containerColor = colorScheme.secondary,
            iconColor = colorScheme.secondaryDim,
            labelColor = colorScheme.onSecondary,
            secondaryLabelColor = colorScheme.onSecondary
        ),
        // ... other parameters
    )

  3. Feste Farben angeben (mit Vorsicht verwenden). Es wird zwar allgemein empfohlen, Farben nach ihrer semantischen Rolle anzugeben (z.B. colorScheme.primary), Sie können aber auch direkte Farbwerte angeben. Dieser Ansatz sollte sparsam verwendet werden, da er zu Inkonsistenzen mit dem Gesamtdesign führen kann, insbesondere wenn sich das Design dynamisch ändert.

    textEdgeButton(
        colors = filledButtonColors().copy(
            containerColor = android.graphics.Color.RED.argb, // Using named colors
            labelColor = 0xFFFFFF00.toInt().argb // Using a hex code for yellow
        ),
        // ... other parameters
    )

Typografie

Weitere Informationen zur effektiven Verwendung von Typografie in Ihren Designs finden Sie im Leitfaden für Typografiedesign.

Um eine visuelle Konsistenz auf der Wear OS-Plattform zu schaffen und die Leistung zu optimieren, wird der gesamte Text auf Kacheln mit einer vom System bereitgestellten Schriftart gerendert. Das bedeutet, dass Kacheln keine benutzerdefinierten Schriftarten unterstützen. Unter Wear OS 6 und höher ist dies eine OEM-spezifische Schriftart. In den meisten Fällen handelt es sich um eine variable Schriftart, die eine ausdrucksstärkere Darstellung und eine detailliertere Steuerung ermöglicht.

Zum Erstellen eines Textstils verwenden Sie normalerweise die Methode text() in Kombination mit typografischen Konstanten. Mit dieser Komponente können Sie vordefinierte Typografierollen in Material 3 Expressive verwenden. So können Sie die etablierten Best Practices für Typografie in Bezug auf Lesbarkeit und Hierarchie einhalten. Die Bibliothek bietet 18 semantische Typografiekonstanten, z. B. BODY_MEDIUM. Diese Konstanten wirken sich auch auf andere Schriftachsen als die Größe aus.

text(
    text = "Hello, World!".layoutString,
    typography = BODY_MEDIUM,
)

Für mehr Kontrolle können Sie zusätzliche Einstellungen angeben. Unter Wear OS 6 und höher wird wahrscheinlich eine variable Schriftart verwendet, die Sie entlang der Achsen Kursiv, Stärke, Breite und Rundung ändern können. Sie können diese Achsen mit dem Parameter settings steuern:

text(
    text = "Hello, World".layoutString,
    italic = true,

    // Use elements defined in androidx.wear.protolayout.LayoutElementBuilders.FontSetting
    settings =
    listOf(
        weight(500),
        width(100F),
        roundness(100)
    ),
)

Wenn Sie die Größe oder den Zeichenabstand steuern müssen (nicht empfohlen), verwenden Sie basicText() anstelle von text() und erstellen Sie mit fontStyle() einen Wert für das Attribut fontStyle.

Form und Ränder

Sie können den Eckenradius fast jeder Komponente mit der Eigenschaft shape ändern. Die Werte stammen aus dem MaterialScope-Attribut shapes:

textButton(
    height = expand(),
    width = expand(),
    shape = shapes.medium, // OR another value like shapes.full
    colors = filledVariantButtonColors(),
    labelContent = { text("Hello, World!".layoutString) },
)

Wenn Sie die Form einer Komponente ändern und der Meinung sind, dass am Rand des Displays zu viel oder zu wenig Platz bleibt, können Sie die Ränder mit dem Parameter margin von primaryLayout() anpassen:

primaryLayout(
    mainSlot = {
        textButton(
            shape = shapes.small,
            /* ... */
        )
    },
    // margin constants defined in androidx.wear.protolayout.material3.PrimaryLayoutMargins
    margins = MAX_PRIMARY_LAYOUT_MARGIN,
)

Bögen

Die folgenden untergeordneten Arc-Container werden unterstützt:

  • ArcLine: Rendert eine gekrümmte Linie um den Bogen.
  • ArcText: Rendert gebogenen Text im Bogen.
  • ArcAdapter: Rendert ein einfaches Layoutelement im Bogen, das tangential zum Bogen gezeichnet wird.

Weitere Informationen finden Sie in der Referenzdokumentation zu den einzelnen Elementtypen.

Modifikatoren

Auf jedes verfügbare Layoutelement können optional Modifikatoren angewendet werden. Verwenden Sie diese Modifikatoren für die folgenden Zwecke:

  • Ändern Sie das Erscheinungsbild des Layouts. Fügen Sie Ihrem Layoutelement beispielsweise einen Hintergrund, einen Rahmen oder einen Abstand hinzu.
  • Fügen Sie Metadaten zum Layout hinzu. Fügen Sie beispielsweise Ihrem Layoutelement einen Semantikmodifikator hinzu, um es mit Screenreadern zu verwenden.
  • Funktionen hinzufügen Fügen Sie beispielsweise dem Layoutelement einen anklickbaren Modifikator hinzu, um die Kachel interaktiv zu machen. Weitere Informationen finden Sie unter Mit Kacheln interagieren.

Sie können beispielsweise das Standarddesign und die Metadaten eines Image anpassen, wie im folgenden Codebeispiel gezeigt:

private fun myImage(): LayoutElement =
    Image.Builder()
        .setWidth(dp(24f))
        .setHeight(dp(24f))
        .setResourceId("image_id")
        .setModifiers(
            Modifiers.Builder()
                .setBackground(Background.Builder().setColor(argb(0xFFFF0000.toInt())).build())
                .setPadding(ModifiersBuilders.Padding.Builder().setStart(dp(12f)).build())
                .setSemantics(Semantics.Builder().setContentDescription("Image description").build())
                .build()
        )
        .build()

Spannables

Ein Spannable ist ein spezieller Containertyp, der Elemente ähnlich wie Text anordnet. Das ist nützlich, wenn Sie einen anderen Stil nur auf einen Teilstring in einem größeren Textblock anwenden möchten. Mit dem Text-Element ist das nicht möglich.

Ein Spannable-Container ist mit Span untergeordneten Elementen gefüllt. Andere untergeordnete Elemente oder verschachtelte Spannable-Instanzen sind nicht zulässig.

Es gibt zwei Arten von untergeordneten Span-Elementen:

  • SpanText: Rendert Text mit einem bestimmten Stil.
  • SpanImage: Rendert ein Bild inline mit Text.

Sie könnten beispielsweise „world“ in einer „Hello world“-Tile kursiv formatieren und ein Bild zwischen den Wörtern einfügen, wie im folgenden Codebeispiel gezeigt:

private fun mySpannable(): LayoutElement =
    LayoutElementBuilders.Spannable.Builder()
        .addSpan(SpanText.Builder().setText("Hello ").build())
        .addSpan(SpanImage.Builder().setWidth(dp(24f)).setHeight(dp(24f)).setResourceId("image_id").build())
        .addSpan(
            SpanText.Builder()
                .setText("world")
                .setFontStyle(FontStyle.Builder().setItalic(true).build())
                .build()
        )
        .build()

Mit Ressourcen arbeiten

Kacheln haben keinen Zugriff auf die Ressourcen Ihrer App. Das bedeutet, dass Sie keine Android-Bild-ID an ein Image-Layoutelement übergeben können, um es aufzulösen. Überschreiben Sie stattdessen die Methode onTileResourcesRequest() und stellen Sie alle Ressourcen manuell bereit.

Es gibt zwei Möglichkeiten, Bilder in der Methode onTileResourcesRequest() bereitzustellen:

override fun onTileResourcesRequest(
    requestParams: ResourcesRequest
) = Futures.immediateFuture(
    Resources.Builder()
        .setVersion("1")
        .addIdToImageMapping(
            "image_from_resource",
            ResourceBuilders.ImageResource.Builder()
                .setAndroidResourceByResId(
                    ResourceBuilders.AndroidImageResourceByResId.Builder()
                        .setResourceId(R.drawable.ic_walk)
                        .build()
                ).build()
        )
        .addIdToImageMapping(
            "image_inline",
            ResourceBuilders.ImageResource.Builder()
                .setInlineResource(
                    ResourceBuilders.InlineImageResource.Builder()
                        .setData(imageAsByteArray)
                        .setWidthPx(48)
                        .setHeightPx(48)
                        .setFormat(ResourceBuilders.IMAGE_FORMAT_RGB_565)
                        .build()
                ).build()
        ).build()
)

Checkliste für Vorschaubilder von Kacheln

Das System zeigt das Vorschaubild der Kachel, auf das im Android-App-Manifest verwiesen wird, im Editor für das Kachelkarussell an, um eine neue Kachel hinzuzufügen. Dieser Editor wird sowohl auf Wear OS-Geräten als auch in der Companion-App für Smartwatches auf Smartphones angezeigt.

Damit Nutzer dieses Vorschaubild optimal nutzen können, sollten Sie die folgenden Details zu Ihrer Kachel prüfen:

  • Spiegelt das aktuelle Design wider. Die Vorschau sollte das aktuelle Design der Tile genau wiedergeben.
  • Verwendet empfohlene Dimensionen. Damit die bestmögliche Anzeigequalität und eine gute Nutzererfahrung gewährleistet sind, sollte das Vorschaubild die Abmessungen 400 × 400 Pixel haben.
  • Verwendet ein statisches Farbschema. Verwenden Sie das statische Farbschema der Kachel, kein dynamisches.
  • Enthält ein App-Symbol. Prüfen Sie, ob das Symbol Ihrer App oben im Vorschaubild angezeigt wird.
  • Zeigt den geladenen/angemeldeten Status an. In der Vorschau sollte ein vollständig funktionsfähiger „geladener“ oder „angemeldeter“ Zustand angezeigt werden. Leere Inhalte oder Platzhalterinhalte sind zu vermeiden.
  • Nutzen Sie Regeln zur Ressourcenauflösung für die Anpassung (optional). Sie können die Regeln für die Ressourcenauflösung von Android verwenden, um Vorschauen bereitzustellen, die der Displaygröße, der Sprache oder den Spracheinstellungen des Geräts entsprechen. Das ist besonders nützlich, wenn die Darstellung der Kachel je nach Gerät variiert.