Wenn Sie Kacheln aus Ihrer Anwendung bereitstellen möchten, fügen Sie die folgenden Abhängigkeiten in die Datei build.gradle
der Anwendung ein.
Groovig
dependencies { // Use to implement support for wear tiles implementation "androidx.wear.tiles:tiles:1.4.0-alpha02" // Use to utilize standard components and layouts in your tiles implementation "androidx.wear.protolayout:protolayout:1.2.0-alpha02" // Use to utilize components and layouts with Material Design in your tiles implementation "androidx.wear.protolayout:protolayout-material:1.2.0-alpha02" // Use to include dynamic expressions in your tiles implementation "androidx.wear.protolayout:protolayout-expression:1.2.0-alpha02" // Use to preview wear tiles in your own app debugImplementation "androidx.wear.tiles:tiles-renderer:1.4.0-alpha02" // Use to fetch tiles from a tile provider in your tests testImplementation "androidx.wear.tiles:tiles-testing:1.4.0-alpha02" }
Kotlin
dependencies { // Use to implement support for wear tiles implementation("androidx.wear.tiles:tiles:1.4.0-alpha02") // Use to utilize standard components and layouts in your tiles implementation("androidx.wear.protolayout:protolayout:1.2.0-alpha02") // Use to utilize components and layouts with Material Design in your tiles implementation("androidx.wear.protolayout:protolayout-material:1.2.0-alpha02") // Use to include dynamic expressions in your tiles implementation("androidx.wear.protolayout:protolayout-expression:1.2.0-alpha02") // Use to preview wear tiles in your own app debugImplementation("androidx.wear.tiles:tiles-renderer:1.4.0-alpha02") // Use to fetch tiles from a tile provider in your tests testImplementation("androidx.wear.tiles:tiles-testing:1.4.0-alpha02") }
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:
Kotlin
// Uses the ProtoLayout namespace for tile timeline objects. // If you haven't done so already, migrate to the ProtoLayout namespace. import androidx.wear.protolayout.TimelineBuilders.Timeline import androidx.wear.protolayout.material.Text import androidx.wear.tiles.TileBuilders.Tile private val RESOURCES_VERSION = "1" 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_DISPLAY1) .setColor(argb(0xFF000000.toInt())) .build())) .build()) override fun onTileResourcesRequest(requestParams: ResourcesRequest) = Futures.immediateFuture(Resources.Builder() .setVersion(RESOURCES_VERSION) .build() ) }
Java
// Uses the ProtoLayout namespace for tile timeline objects. // If you haven't done so already, migrate to the ProtoLayout namespace. import androidx.wear.protolayout.TimelineBuilders.Timeline; import androidx.wear.protolayout.material.Text; import androidx.wear.tiles.TileBuilders.Tile; public class MyTileService extends TileService { private static final String RESOURCES_VERSION = "1"; @NonNull @Override protected ListenableFuture<Tile> onTileRequest( @NonNull TileRequest requestParams ) { return Futures.immediateFuture(new Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setTileTimeline( Timeline.fromLayoutElement( new Text.Builder(this, "Hello world!") .setTypography(Typography.TYPOGRAPHY_DISPLAY1) .setColor(ColorBuilders.argb(0xFF000000)) .build())) .build() ); } @NonNull @Override protected ListenableFuture<Resources> onTileResourcesRequest( @NonNull ResourcesRequest requestParams ) { return Futures.immediateFuture(new Resources.Builder() .setVersion(RESOURCES_VERSION) .build() ); } }
Als Nächstes fügen Sie einen Dienst in das <application>
-Tag der Datei AndroidManifest.xml
ein.
<service android:name=".MyTileService" android:label="@string/tile_label" android:description="@string/tile_description" android:icon="@drawable/tile_icon_round" android:roundIcon="@drawable/tile_icon_round" 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 registrieren diesen Dienst als Kachelanbieter.
Das Symbol, das Label und die Beschreibung werden dem Nutzer angezeigt, wenn er Kacheln auf seinem Smartphone oder seiner Uhr konfiguriert.
Verwenden Sie das Vorschau-Metadaten-Tag, um eine Vorschau der Kachel anzuzeigen, wenn Sie sie auf Ihrem Smartphone konfigurieren.
Lebenszyklus des Tile-Dienstes
Nachdem Sie die TileService
in Ihrem App-Manifest erstellt und deklariert haben, können Sie auf die Statusänderungen des Tile-Dienstes reagieren.
TileService
ist ein gebundener Dienst. Ihr TileService
ist aufgrund Ihrer Anwendungsanfrage oder wenn das System mit ihr kommunizieren muss, gebunden. Ein typischer Lebenszyklus von gebundenen Diensten enthält die folgenden vier Callback-Methoden: onCreate()
, onBind()
, onUnbind()
und onDestroy()
. Das System ruft diese Methoden jedes Mal auf, wenn der Dienst in eine neue Lebenszyklusphase eintritt.
Zusätzlich zu den Callbacks, die den Lebenszyklus des gebundenen Dienstes steuern, können Sie weitere Methoden implementieren, die für den TileService
-Lebenszyklus spezifisch sind. Alle Kacheldienste müssen onTileRequest()
und onTileResourcesRequest()
implementieren, um auf Aktualisierungsanfragen vom System zu antworten.
onTileAddEvent()
: Das System ruft diese Methode nur auf, wenn der Nutzer die Kachel zum ersten Mal hinzufügt und wenn der Nutzer die Kachel entfernt und noch einmal hinzufügt. Dies ist der beste Zeitpunkt für eine einmalige Initialisierung.onTileAddEvent()
wird nur aufgerufen, wenn der Satz von Kacheln neu konfiguriert wird, und nicht, wenn eine Kachel vom System erstellt wird. Wenn das Gerät beispielsweise neu gestartet oder eingeschaltet wird, wirdonTileAddEvent()
für die bereits hinzugefügten Kacheln nicht aufgerufen. Sie können stattdessengetActiveTilesAsync()
verwenden, um eine Übersicht darüber zu erhalten, welche Kacheln zu Ihnen aktiv sind.onTileRemoveEvent()
: Das System ruft diese Methode nur auf, wenn der Nutzer die Kachel entfernt.onTileEnterEvent()
: Diese Methode wird vom System aufgerufen, wenn eine von diesem Anbieter bereitgestellte Kachel auf dem Bildschirm erscheint.onTileLeaveEvent()
: Diese Methode wird vom System aufgerufen, wenn eine von diesem Anbieter bereitgestellte Kachel auf dem Bildschirm nicht mehr sichtbar ist.onTileRequest()
: Das System ruft diese Methode auf, wenn das System eine neue Zeitachse von diesem Anbieter anfordert.onTileResourcesRequest()
: Das System ruft diese Methode auf, wenn das System ein Ressourcen-Bundle von diesem Anbieter anfordert. Dies kann beim ersten Laden einer Kachel oder beim Ändern der Ressourcenversion passieren.
Aktive Kacheln abfragen
Aktive Kacheln sind Kacheln, die zur Anzeige auf der Smartwatch hinzugefügt wurden. Verwenden Sie die statische Methode getActiveTilesAsync()
von TileService
, um abzufragen, welche Kacheln zu Ihrer Anwendung aktiv sind.
Benutzeroberfläche für Kacheln erstellen
Das Layout einer Kachel wird mithilfe eines Builder-Musters geschrieben. Das Layout einer Kachel ist wie eine Baumstruktur aufgebaut, die aus Layoutcontainern und grundlegenden Layoutelementen besteht. Jedes Layoutelement verfügt über Eigenschaften, die Sie mithilfe verschiedener Setter-Methoden festlegen können.
Grundlegende Layoutelemente
Die folgenden visuellen Elemente aus der protolayout
-Bibliothek werden zusammen mit Material Components unterstützt:
Text
: rendert einen Textstring mit optionalem Zeilenumbruch.Image
: Damit wird ein Bild gerendert.Spacer
: Bietet einen Innenabstand zwischen Elementen oder kann beim Festlegen der Hintergrundfarbe als Trennlinie dienen.
Materialkomponenten
Zusätzlich zu den Grundelementen enthält die protolayout-material
-Bibliothek Komponenten, die ein Kacheldesign gemäß den Empfehlungen von Material Design für die Benutzeroberfläche gewährleisten.
Button
: anklickbare runde Komponente, die ein Symbol enthältChip
: anklickbare stadiumförmige Komponente, die bis zu zwei Textzeilen und ein optionales Symbol enthalten kann.CompactChip
: anklickbare Komponente in Stadionform, die eine Textzeile enthältTitleChip
: anklickbare stadionförmige Komponente, ähnlich wieChip
, aber mit einer größeren Höhe für den Titeltext.CircularProgressIndicator
: runde Fortschrittsanzeige, die innerhalb einerEdgeContentLayout
platziert werden kann, um den Fortschritt an den Bildschirmrändern anzuzeigen.
Layoutcontainer
Folgende Container sowie Materiallayouts werden unterstützt:
Row
: Legt untergeordnete Elemente horizontal hintereinander an.Column
: Legt untergeordnete Elemente vertikal nacheinander an.Box
: Untergeordnete Elemente werden übereinandergelegt.Arc
: legt untergeordnete Elemente in einem Kreis an.Spannable
: WendetFontStyles
auf Textabschnitte an, zusammen mit verschachtelten Texten und Bildern. Weitere Informationen finden Sie unter Spannables.
Jeder Container kann ein oder mehrere untergeordnete Elemente enthalten, die wiederum Container sein können. Beispielsweise kann ein Column
mehrere Row
-Elemente als untergeordnete Elemente enthalten, was zu einem rasterähnlichen 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 grundlegenden Layouts bietet die protolayout-material
-Bibliothek einige überzeugende Layouts, die darauf ausgelegt sind, Elemente in bestimmten Anzeigenflächen zu halten.
PrimaryLayout
: platziert eine einzelne primäre AktionCompactChip
am unteren Rand, wobei der Inhalt darüber zentriert wird.MultiSlotLayout
: Positioniert primäre und sekundäre Labels mit optionalem Inhalt dazwischen und einem optionalenCompactChip
am unteren Rand.MultiButtonLayout
: Positioniert eine Reihe von Schaltflächen, die gemäß den Materialrichtlinien angeordnet sind.EdgeContentLayout
: Hiermit werden Inhalte am Bildschirmrand (z. B.CircularProgressIndicator
) positioniert. Bei Verwendung dieses Layouts werden die entsprechenden Ränder und die entsprechenden Abstände automatisch auf den Inhalt angewendet.
Bögen
Die folgenden untergeordneten Arc
-Container werden unterstützt:
ArcLine
: Damit wird eine kurvenförmige Linie um den Bogen herum gerendert.ArcText
: Damit wird gebogener Text im Bogen gerendert.ArcAdapter
: Damit wird ein grundlegendes Layoutelement im Bogen gerendert, das auf einer Tangente 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. Sie können diese Modifikatoren für folgende Zwecke verwenden:
- das visuelle Erscheinungsbild des Layouts ändern. Sie können Ihrem Layoutelement z. B. einen Hintergrund, einen Rahmen oder einen Abstand hinzufügen.
- Fügen Sie Metadaten zum Layout hinzu. Beispielsweise können Sie Ihrem Layoutelement einen Semantikmodifikator für die Verwendung mit Screenreadern hinzufügen.
- Funktionen hinzufügen Sie können z. B. Ihrem Layoutelement einen anklickbaren Modifikator hinzufügen, um die Kachel interaktiv zu gestalten. Weitere Informationen findest du unter Mit Kacheln interagieren.
Beispielsweise können wir das Standarddesign und die Standardmetadaten eines 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(); }
Spannables
Ein Spannable
ist ein besonderer Containertyp, der Elemente ähnlich wie Text anordnet. Das ist nützlich, wenn Sie nur auf einen Teilstring in einem größeren Textblock einen anderen Stil anwenden möchten, was mit dem Element Text
nicht möglich ist.
Ein Spannable
-Container enthält untergeordnete Span
. Andere untergeordnete oder verschachtelte Spannable
-Instanzen sind nicht zulässig.
Es gibt zwei Arten von untergeordneten Span
-Elementen:
SpanText
: Text mit einem bestimmten Stil wird gerendert.SpanImage
: Damit wird ein Bild inline mit Text gerendert.
Sie können beispielsweise „world“ in einer Kachel „Hello world“ kursiv darstellen und zwischen den Wörtern ein Bild 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
Kacheln haben keinen Zugriff auf die Ressourcen Ihrer App. Das bedeutet, dass Sie eine Android-Bild-ID nicht an ein Image
-Layoutelement übergeben können und erwarten, dass es aufgelöst wird. Überschreiben Sie stattdessen die Methode onTileResourcesRequest()
und geben Sie alle Ressourcen manuell an.
Es gibt zwei Möglichkeiten, Bilder mit der Methode onTileResourcesRequest()
bereitzustellen:
- Stelle mit
setAndroidResourceByResId()
eine Drawable-Ressource bereit. - Stellen Sie mithilfe von
setInlineResource()
ein dynamisches Bild alsByteArray
bereit.
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.
- Aktive Daten und Trainings
- Passive Datenaktualisierungen
- Ladebildschirm hinzufügen