Um mit der Bereitstellung von Kacheln aus Ihrer App zu beginnen, schließen Sie die folgenden Abhängigkeiten in
die Datei build.gradle
Ihrer App.
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
Um eine Kachel aus Ihrer Anwendung bereitzustellen, erstellen Sie eine Klasse, die das
TileService
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() ); } }
Fügen Sie als Nächstes einen Dienst im <application>
-Tag Ihres
AndroidManifest.xml
-Datei.
<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 registriert diesen Dienst als Kachelanbieter.
Das Symbol, das Label und die Beschreibung werden dem Nutzer angezeigt, wenn er Kacheln konfiguriert auf dem Smartphone oder der Smartwatch.
Mit dem Metadaten-Tag für die Vorschau können Sie bei der Konfiguration eine Vorschau der Kachel anzeigen lassen auf deinem Smartphone.
Übersicht über den Lebenszyklus des Tile-Dienstes
Nachdem du TileService
in deinem App-Manifest erstellt und deklariert hast,
auf Statusänderungen des Kacheldienstes reagieren kann.
TileService
ist ein gebundener Dienst. Als Ergebnis ist Ihre TileService
gebunden
oder ob das System mit ihr kommunizieren muss. Ein typisches
bound-service life enthält die folgenden vier Callback-Methoden:
onCreate()
, onBind()
, onUnbind()
und
onDestroy()
. Das System ruft diese Methoden jedes Mal auf, wenn der Dienst
eine neue Lebenszyklusphase beginnt.
Zusätzlich zu den Callbacks, die den Lebenszyklus des gebundenen Dienstes steuern, können Sie
Implementieren Sie weitere Methoden, die für den TileService
-Lebenszyklus spezifisch sind. Alle Kacheln
Dienste müssen onTileRequest()
und onTileResourcesRequest()
implementieren, um
auf Systemanforderungen zu reagieren.
onTileAddEvent()
: Das System ruft diese Methode nur auf, wenn der Nutzer fügt Ihre Kachel zum ersten Mal hinzu. Wenn der Nutzer Ihre Kachel entfernt und hinzufügt, erneut öffnen. Dies ist der beste Zeitpunkt für eine einmalige Initialisierung.onTileAddEvent()
wird nur aufgerufen, wenn der Satz von Kacheln neu konfiguriert ist. nicht, wenn eine Kachel vom System erstellt wird. Beispiel: Wenn das Gerät neu gestartet oder eingeschaltet ist, wirdonTileAddEvent()
für die Kacheln nicht aufgerufen die bereits hinzugefügt wurden. Sie könnengetActiveTilesAsync()
verwenden um zu sehen, welche Kacheln zu Ihnen gehören aktiv sind.onTileRemoveEvent()
: Das System ruft diese Methode nur auf, wenn der Nutzer entfernt Ihre Kachel.onTileEnterEvent()
: Das System ruft diese Methode auf, wenn eine Kachel die von diesem Anbieter bereitgestellt wurden, auf dem Bildschirm zu sehen sind.onTileLeaveEvent()
: Das System ruft diese Methode auf, wenn eine Kachel die von diesem Anbieter bereitgestellt wurden, nicht auf dem Bildschirm zu sehen sind.onTileRequest()
: Das System ruft diese Methode auf, wenn das System fordert von diesem Anbieter eine neue Zeitachse an.onTileResourcesRequest()
: Das System ruft diese Methode auf, wenn der fordert das System ein Ressourcenpaket von diesem Anbieter an. Das kann passieren, wenn eine Kachel zum ersten Mal geladen wird oder wenn die Ressourcenversion Änderungen.
Abfrage, welche Tiles aktiv sind
Aktive Kacheln sind Kacheln, die für die Anzeige auf der Smartwatch hinzugefügt wurden. Verwenden Sie
Die statische Methode getActiveTilesAsync()
von TileService
zum Abfragen der Kacheln
die zu deiner App gehören, aktiv sind.
UI für Kacheln erstellen
Das Layout einer Kachel wird mithilfe eines Builder-Musters geschrieben. Das Layout einer Kachel ist die wie ein Baum aufgebaut sind und aus Layoutcontainern und einem einfachen Layout Elemente. Jedes Layoutelement verfügt über Eigenschaften, die Sie über verschiedene Setter-Methoden.
Grundlegende Layoutelemente
Die folgenden visuellen Elemente aus der protolayout
-Bibliothek werden unterstützt:
zusammen mit den Material Components:
Text
: wird gerendert einen Textstring mit optionalem Zeilenumbruch.Image
: ein Bild rendert.Spacer
: bietet Abstände zwischen Elementen oder kann als Trennelement dienen, wenn Sie seine die Hintergrundfarbe.
Materialkomponenten
Zusätzlich zu den Grundelementen bietet die protolayout-material
-Bibliothek
Komponenten, die ein Kacheldesign im Einklang mit der Benutzeroberfläche von Material Design sicherstellen
Empfehlungen.
Button
: anklickbar kreisförmige Komponente, die ein Symbol enthalten soll.Chip
: anklickbar stadionförmige Komponente, die bis zu zwei Textzeilen und ein optionales Symbol.CompactChip
: anklickbare, stadionförmige Komponente, die eine Textzeile enthalten soll.TitleChip
: anklickbare, stadionförmige Komponente ähnlich wieChip
, aber mit einem größeren Höhe für den Titeltext.CircularProgressIndicator
: eine kreisförmige Fortschrittsanzeige,EdgeContentLayout
, um den Fortschritt am Rand des Bildschirm.
Layoutcontainer
Die folgenden Container werden zusammen mit dem Element Material unterstützt. Layouts:
Row
: Legenden untergeordnete Elemente horizontal nacheinander angeordnet.Column
: legt untergeordnete Elemente vertikal nacheinander an.Box
: Overlays untergeordnete Elemente übereinander liegen.Arc
: Legenden untergeordnete Elemente in einem Kreis.Spannable
: wendet spezifischeFontStyles
in Textabschnitte und verschränkte Texte und Bilder. Weitere Informationen Weitere Informationen finden Sie unter Spannables.
Jeder Container kann ein oder mehrere untergeordnete Elemente enthalten, die wiederum
Container. Ein Column
kann beispielsweise mehrere Row
-Elemente wie folgt enthalten:
untergeordneten Elementen, was zu einem rasterähnlichen Layout führt.
Beispiel: Eine Kachel mit einem Container-Layout und zwei untergeordneten Layout-Elementen könnte wie folgt 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
Neben den grundlegenden Layouts bietet die protolayout-material
-Bibliothek einige
Spezielle Layouts, die darauf ausgelegt sind, Elemente in bestimmten „Slots“ zu halten.
PrimaryLayout
: platziert eine primäre AktionCompactChip
unten mit dem Inhalte in der Mitte darüber.MultiSlotLayout
: Positionierung von primären und sekundären Labels mit optionalen Inhalten zwischen und eine optionaleCompactChip
am unteren Rand.MultiButtonLayout
: platziert eine Reihe von Schaltflächen, die nach Material Design .EdgeContentLayout
: Position von Inhalten am Rand eines Bildschirms, z. B.CircularProgressIndicator
. Bei Verwendung dieses Layouts werden die darin enthaltenen Inhalte werden automatisch die passenden Ränder und die entsprechenden Abstände angewendet.
Bögen
Die folgenden untergeordneten Arc
-Container werden unterstützt:
ArcLine
: rendert eine gebogene Linie um den BogenArcText
: rendert den gekrümmten Text im BogenArcAdapter
: Rendert ein grundlegendes Layoutelement im Bogen, das tangens zum Bogen gezeichnet wird.
Weitere Informationen finden Sie in der Referenzdokumentation für jeden der Elementtypen.
Modifikatoren
Auf jedes verfügbare Layoutelement können optional Modifikatoren angewendet werden. Verwenden Sie diese Modifikatoren für folgende Zwecke nutzen:
- Das visuelle Erscheinungsbild des Layouts ändern. Fügen Sie beispielsweise einen Hintergrund, Rahmen oder Abstand zum Layoutelement.
- Fügen Sie Metadaten zum Layout hinzu. Fügen Sie beispielsweise einen Semantikmodifikator zu Ihrem Layoutelement zur Verwendung mit Screenreadern.
- Fügen Sie Funktionen hinzu. Fügen Sie Ihrem Layout beispielsweise einen anklickbaren Modifikator hinzu. -Element, um Ihre Kachel interaktiv zu machen. Weitere Informationen finden Sie unter Mit Kacheln interagieren
Beispielsweise können wir das Standarddesign und die Metadaten eines
Image
, wie gezeigt
im folgenden Codebeispiel:
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 eine spezielle Art von Container, der Elemente ähnlich
Text. Dies ist nützlich, wenn Sie einen anderen Stil
Teilzeichenfolge in einen größeren Textblock einfügen, was mit der
Text
-Element.
Ein Spannable
-Container ist gefüllt mit
Span
Kinder. Andere untergeordnete Elemente oder verschachtelte Spannable
-Instanzen sind nicht zulässig.
Es gibt zwei Arten von untergeordneten Span
-Elementen:
Sie können z. B. „Welt“ kursiv formatieren. in einem „Hello World“-Element Kachel und eine zwischen den Wörtern ein, wie im folgenden Codebeispiel veranschaulicht:
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 deiner App. Das bedeutet, dass Sie
kann keine Android-Bild-ID an ein Image
-Layoutelement übergeben und erwartet,
gelöst werden muss. Überschreiben Sie stattdessen
onTileResourcesRequest()
und stellen alle Ressourcen manuell bereit.
Es gibt zwei Möglichkeiten, Bilder im onTileResourcesRequest()
bereitzustellen.
:
- Stelle eine Drawable-Ressource mit
setAndroidResourceByResId()
- Stellen Sie ein dynamisches Bild als
ByteArray
mithilfe vonsetInlineResource()
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 Schnelleinstellungen für Apps erstellen