Wenn Sie Kacheln über Ihre App bereitstellen möchten, fügen Sie der build.gradle
-Datei Ihrer App die folgenden Abhängigkeiten hinzu.
Groovy
dependencies { // Use to implement support for wear tiles implementation "androidx.wear.tiles:tiles:1.5.0-alpha04" // Use to utilize standard components and layouts in your tiles implementation "androidx.wear.protolayout:protolayout:1.3.0-alpha04" // Use to utilize components and layouts with Material Design in your tiles implementation "androidx.wear.protolayout:protolayout-material:1.3.0-alpha04" // Use to include dynamic expressions in your tiles implementation "androidx.wear.protolayout:protolayout-expression:1.3.0-alpha04" // Use to preview wear tiles in your own app debugImplementation "androidx.wear.tiles:tiles-renderer:1.5.0-alpha04" // Use to fetch tiles from a tile provider in your tests testImplementation "androidx.wear.tiles:tiles-testing:1.5.0-alpha04" }
Kotlin
dependencies { // Use to implement support for wear tiles implementation("androidx.wear.tiles:tiles:1.5.0-alpha04") // Use to utilize standard components and layouts in your tiles implementation("androidx.wear.protolayout:protolayout:1.3.0-alpha04") // Use to utilize components and layouts with Material Design in your tiles implementation("androidx.wear.protolayout:protolayout-material:1.3.0-alpha04") // Use to include dynamic expressions in your tiles implementation("androidx.wear.protolayout:protolayout-expression:1.3.0-alpha04") // Use to preview wear tiles in your own app debugImplementation("androidx.wear.tiles:tiles-renderer:1.5.0-alpha04") // Use to fetch tiles from a tile provider in your tests testImplementation("androidx.wear.tiles:tiles-testing:1.5.0-alpha04") }
Kachel erstellen
Wenn Sie eine Kachel aus Ihrer Anwendung bereitstellen möchten, erstellen Sie eine Klasse, die TileService
erweitert, und implementieren Sie die Methoden, wie im folgenden Codebeispiel gezeigt:
class MyTileService : TileService() { override fun onTileRequest(requestParams: RequestBuilders.TileRequest) = Futures.immediateFuture( Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setTileTimeline( Timeline.fromLayoutElement( Text.Builder(this, "Hello World!") .setTypography(Typography.TYPOGRAPHY_BODY1) .setColor(argb(0xFFFFFFFF.toInt())) .build() ) ) .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.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>
Der Berechtigungs- und Intent-Filter registriert diesen Dienst als Ansichtsanbieter.
Das Symbol, das Label und die Beschreibung werden dem Nutzer angezeigt, wenn er Kacheln auf seinem Smartphone oder seiner Smartwatch konfiguriert.
Mit dem Metadaten-Tag „preview“ können Sie eine Vorschau der Kachel anzeigen lassen, wenn Sie sie auf Ihrem Smartphone konfigurieren.
Übersicht über den Lebenszyklus von Webkarten-Diensten
Nachdem Sie Ihre TileService
in Ihrem App-Manifest erstellt und deklariert haben, können Sie auf Statusänderungen des Ansichtsdienstes reagieren.
TileService
ist ein gebundener Dienst. Ihre TileService
wird aufgrund Ihrer App-Anfrage oder wenn das System mit ihr kommunizieren muss, gebunden. Ein typischer Lebenszyklus eines gebundenen Dienstes umfasst die folgenden vier Rückrufmethoden: onCreate()
, onBind()
, onUnbind()
und onDestroy()
. Das System ruft diese Methoden jedes Mal auf, wenn der Dienst eine neue Lebenszyklusphase betritt.
Zusätzlich zu den Callbacks, die den Lebenszyklus des verknüpften Dienstes steuern, können Sie andere Methoden implementieren, die speziell für den TileService
-Lebenszyklus gelten. Alle Kacheldienste müssen onTileRequest()
und onTileResourcesRequest()
implementieren, um auf Aktualisierungsanfragen des Systems zu reagieren.
onTileAddEvent()
: Das System ruft diese Methode nur auf, wenn der Nutzer Ihre Kachel zum ersten Mal hinzufügt und wenn er sie wieder entfernt und hinzufügt. Dies ist der beste Zeitpunkt für eine einmalige Initialisierung.onTileAddEvent()
wird nur aufgerufen, wenn die Ansicht neu konfiguriert wird, nicht jedes Mal, wenn eine Kachel vom System erstellt wird. Wenn das Gerät beispielsweise neu gestartet oder eingeschaltet wird, wirdonTileAddEvent()
nicht für die bereits hinzugefügten Kacheln aufgerufen. Sie können stattdessengetActiveTilesAsync()
verwenden, um einen Snapshot der aktiven Ihren eigenen Kacheln zu erhalten.onTileRemoveEvent()
: Das System ruft diese Methode nur auf, wenn der Nutzer Ihre Kachel entfernt.onTileEnterEvent()
: Diese Methode wird vom System aufgerufen, wenn eine vom Anbieter bereitgestellte Kachel auf dem Bildschirm sichtbar wird.onTileLeaveEvent()
: Das System ruft diese Methode auf, wenn eine Kachel dieses Anbieters nicht mehr auf dem Bildschirm sichtbar ist.onTileRequest()
: Diese Methode wird vom System aufgerufen, wenn es einen neuen Zeitplan von diesem Anbieter anfordert.onTileResourcesRequest()
: Diese Methode wird vom System aufgerufen, wenn es ein Ressourcenpaket von diesem Anbieter anfordert. Das kann beim ersten Laden einer Kachel oder bei jeder Änderung der Ressourcenversion passieren.
Abfragen, welche Kacheln aktiv sind
Aktive Ansichten sind Ansichten, die zur Anzeige auf der Smartwatch hinzugefügt wurden. Verwenden Sie die statische Methode getActiveTilesAsync()
von TileService
, um abzufragen, welche Kacheln zu Ihrer App gehören und aktiv sind.
Benutzeroberfläche für Kacheln erstellen
Das Layout einer Kachel wird mit einem Builder-Muster geschrieben. Das Layout einer Kachel ist wie ein Baum aufgebaut, der aus Layoutcontainern und grundlegenden Layoutelementen besteht. Jedes Layoutelement hat Eigenschaften, die Sie über verschiedene Setzermethoden festlegen können.
Grundlegende Layoutelemente
Neben Materialkomponenten werden die folgenden visuellen Elemente aus der protolayout
-Bibliothek unterstützt:
Text
: Rendert einen Textstring, optional mit Umbruch.Image
: rendert ein Bild.Spacer
: Bietet einen Abstand zwischen Elementen oder kann als Trennlinie dienen, wenn Sie die Hintergrundfarbe festlegen.
Materialkomponenten
Neben den grundlegenden Elementen bietet die protolayout-material
-Bibliothek Komponenten, die für ein Kachelndesign sorgen, das den Empfehlungen für die Material Design-Benutzeroberfläche entspricht.
Button
: Klickbare kreisförmige Komponente, die ein Symbol enthalten soll.Chip
: Klickbare, stadionförmige Komponente, die bis zu zwei Textzeilen und ein optionales Symbol enthalten kann.CompactChip
: Klickbare, stadionförmige Komponente, die eine Textzeile enthalten kann.TitleChip
: Anklickbare, stadionförmige Komponente, ähnlich wieChip
, aber mit größerer Höhe für Titeltext.CircularProgressIndicator
: Kreisförmige Fortschrittsanzeige, die in einemEdgeContentLayout
platziert werden kann, um den Fortschritt am Bildschirmrand anzuzeigen.
Layoutcontainer
Die folgenden Container werden zusammen mit Material-Layouts unterstützt:
Row
: Hier werden untergeordnete Elemente horizontal nacheinander angeordnet.Column
:ordnet untergeordnete Elemente vertikal an, nacheinander.Box
: Hier werden untergeordnete Elemente übereinander gelegt.Arc
: Die untergeordneten Elemente werden in einem Kreis angeordnet.Spannable
: Hiermit werden bestimmteFontStyles
auf Textabschnitte angewendet und Text und Bilder werden miteinander verschachtelt. Weitere Informationen finden Sie unter Spannbare Elemente.
Jeder Container kann ein oder mehrere untergeordnete Elemente enthalten, die selbst auch Container sein können. Ein Column
kann beispielsweise mehrere Row
-Elemente als untergeordnete Elemente enthalten, was zu einem gitterartigen Layout führt.
Eine Kachel mit einem Containerlayout und zwei untergeordneten Layoutelementen könnte beispielsweise so aussehen:
Kotlin
private fun myLayout(): LayoutElement = Row.Builder() .setWidth(wrap()) .setHeight(expand()) .setVerticalAlignment(VALIGN_BOTTOM) .addContent(Text.Builder() .setText("Hello world") .build() ) .addContent(Image.Builder() .setResourceId("image_id") .setWidth(dp(24f)) .setHeight(dp(24f)) .build() ).build()
Java
private LayoutElement myLayout() { return new Row.Builder() .setWidth(wrap()) .setHeight(expand()) .setVerticalAlignment(VALIGN_BOTTOM) .addContent(new Text.Builder() .setText("Hello world") .build() ) .addContent(new Image.Builder() .setResourceId("image_id") .setWidth(dp(24f)) .setHeight(dp(24f)) .build() ).build(); }
Material-Layouts
Zusätzlich zu den einfachen Layouts bietet die protolayout-material
-Bibliothek einige vordefinierte Layouts, die Elemente in bestimmten „Slots“ aufnehmen.
PrimaryLayout
: Posiert eine einzelne primäre AktionCompactChip
unten und zentriert den Inhalt darüber.MultiSlotLayout
: Primäre und sekundäre Labels werden mit optionalem Inhalt dazwischen und einem optionalenCompactChip
unten platziert.MultiButtonLayout
: Posiert eine Reihe von Schaltflächen, die gemäß den Material Design-Richtlinien angeordnet sind.EdgeContentLayout
: Mit dieser Option können Sie Inhalte am Bildschirmrand platzieren, z. B. einCircularProgressIndicator
. Bei diesem Layout werden die entsprechenden Ränder und Abstände für den Inhalt automatisch angewendet.
Bögen
Die folgenden untergeordneten Elemente von Arc
-Containern werden unterstützt:
ArcLine
: Mit dieser Option wird eine gebogene Linie um den Bogen gerendert.ArcText
: Mit dieser Option wird Text im Bogen gerendert.ArcAdapter
: Mit diesem Befehl wird ein einfaches Layoutelement im Bogen gerendert, 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 dem Layoutelement beispielsweise einen Hintergrund, einen Rahmen oder einen Abstand hinzu.
- Fügen Sie Metadaten zum Layout hinzu. Fügen Sie Ihrem Layoutelement beispielsweise einen semantischen Modifikator für die Verwendung mit Screenreadern hinzu.
- Funktionen hinzufügen Fügen Sie Ihrem Layoutelement beispielsweise einen anklickbaren Modifier hinzu, um die Kachel interaktiv zu machen. Weitere Informationen finden Sie unter Mit Kacheln interagieren.
So können wir beispielsweise das Standard-Aussehen und die Metadaten einer Image
anpassen, wie im folgenden Codebeispiel gezeigt:
Kotlin
private fun myImage(): LayoutElement = Image.Builder() .setWidth(dp(24f)) .setHeight(dp(24f)) .setResourceId("image_id") .setModifiers(Modifiers.Builder() .setBackground(Background.Builder().setColor(argb(0xFFFF0000)).build()) .setPadding(Padding.Builder().setStart(dp(12f)).build()) .setSemantics(Semantics.builder() .setContentDescription("Image description") .build() ).build() ).build()
Java
private LayoutElement myImage() { return new Image.Builder() .setWidth(dp(24f)) .setHeight(dp(24f)) .setResourceId("image_id") .setModifiers(new Modifiers.Builder() .setBackground(new Background.Builder().setColor(argb(0xFFFF0000)).build()) .setPadding(new Padding.Builder().setStart(dp(12f)).build()) .setSemantics(new Semantics.Builder() .setContentDescription("Image description") .build() ).build() ).build(); }
Expandable-Anzeigen
Ein Spannable
ist ein spezieller Containertyp, in dem Elemente ähnlich wie Text angeordnet werden. Das ist nützlich, wenn Sie nur einem Teilstring in einem größeren Textblock einen anderen Stil zuweisen möchten. Das ist mit dem Element Text
nicht möglich.
Ein Spannable
-Container ist mit Kindern gefüllt, die Span
sind. Andere untergeordnete Elemente oder verschachtelte Spannable
-Instanzen sind nicht zulässig.
Es gibt zwei Arten von Span
-Unterelementen:
SpanText
: Text wird in einem bestimmten Stil gerendert.SpanImage
: Mit diesem Tag wird ein Bild inline mit dem Text gerendert.
Sie können beispielsweise „Welt“ in einer Kachel „Hallo Welt“ kursiv formatieren und ein Bild zwischen die Wörter einfügen, wie im folgenden Codebeispiel gezeigt:
Kotlin
private fun mySpannable(): LayoutElement = 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()
Java
private LayoutElement mySpannable() { return new Spannable.Builder() .addSpan(new SpanText.Builder() .setText("Hello ") .build() ) .addSpan(new SpanImage.Builder() .setWidth(dp(24f)) .setHeight(dp(24f)) .setResourceId("image_id") .build() ) .addSpan(new SpanText.Builder() .setText("world") .setFontStyle(newFontStyle.Builder() .setItalic(true) .build()) .build() ).build(); }
Mit Ressourcen arbeiten
Ansichten haben keinen Zugriff auf die Ressourcen Ihrer App. Das bedeutet, dass Sie einer Image
-Layout-Komponente keine Android-Bild-ID übergeben können und erwarten können, dass sie aufgelöst wird. Überschreiben Sie stattdessen die Methode onTileResourcesRequest()
und geben Sie alle Ressourcen manuell an.
Es gibt zwei Möglichkeiten, Bilder in der onTileResourcesRequest()
-Methode anzugeben:
- Geben Sie mit
setAndroidResourceByResId()
eine Zeichnen-Ressource an. - Geben Sie ein dynamisches Bild als
ByteArray
mitsetInlineResource()
an.
Kotlin
override fun onTileResourcesRequest( requestParams: ResourcesRequest ) = Futures.immediateFuture( Resources.Builder() .setVersion("1") .addIdToImageMapping("image_from_resource", ImageResource.Builder() .setAndroidResourceByResId(AndroidImageResourceByResId.Builder() .setResourceId(R.drawable.image_id) .build() ).build() ) .addIdToImageMapping("image_inline", ImageResource.Builder() .setInlineResource(InlineImageResource.Builder() .setData(imageAsByteArray) .setWidthPx(48) .setHeightPx(48) .setFormat(ResourceBuilders.IMAGE_FORMAT_RGB_565) .build() ).build() ).build() )
Java
@Override protected ListenableFuture<Resources> onTileResourcesRequest( @NonNull ResourcesRequest requestParams ) { return Futures.immediateFuture( new Resources.Builder() .setVersion("1") .addIdToImageMapping("image_from_resource", new ImageResource.Builder() .setAndroidResourceByResId(new AndroidImageResourceByResId.Builder() .setResourceId(R.drawable.image_id) .build() ).build() ) .addIdToImageMapping("image_inline", new ImageResource.Builder() .setInlineResource(new InlineImageResource.Builder() .setData(imageAsByteArray) .setWidthPx(48) .setHeightPx(48) .setFormat(ResourceBuilders.IMAGE_FORMAT_RGB_565) .build() ).build() ).build() ); }
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Zu ProtoLayout-Namespaces migrieren
ConstraintLayout
in „Schreiben“- Benutzerdefinierte Kacheln für die Schnelleinstellungen für Ihre App erstellen