Pour commencer à fournir des cartes à partir de votre application, incluez les dépendances suivantes dans le fichier build.gradle
de votre application.
Groovy
dependencies { // Use to implement support for wear tiles implementation "androidx.wear.tiles:tiles:1.5.0-alpha05" // Use to utilize standard components and layouts in your tiles implementation "androidx.wear.protolayout:protolayout:1.3.0-alpha05" // Use to utilize components and layouts with Material Design in your tiles implementation "androidx.wear.protolayout:protolayout-material:1.3.0-alpha05" // Use to include dynamic expressions in your tiles implementation "androidx.wear.protolayout:protolayout-expression:1.3.0-alpha05" // Use to preview wear tiles in your own app debugImplementation "androidx.wear.tiles:tiles-renderer:1.5.0-alpha05" // Use to fetch tiles from a tile provider in your tests testImplementation "androidx.wear.tiles:tiles-testing:1.5.0-alpha05" }
Kotlin
dependencies { // Use to implement support for wear tiles implementation("androidx.wear.tiles:tiles:1.5.0-alpha05") // Use to utilize standard components and layouts in your tiles implementation("androidx.wear.protolayout:protolayout:1.3.0-alpha05") // Use to utilize components and layouts with Material Design in your tiles implementation("androidx.wear.protolayout:protolayout-material:1.3.0-alpha05") // Use to include dynamic expressions in your tiles implementation("androidx.wear.protolayout:protolayout-expression:1.3.0-alpha05") // Use to preview wear tiles in your own app debugImplementation("androidx.wear.tiles:tiles-renderer:1.5.0-alpha05") // Use to fetch tiles from a tile provider in your tests testImplementation("androidx.wear.tiles:tiles-testing:1.5.0-alpha05") }
Créer une carte
Pour fournir une carte à partir de votre application, créez une classe qui étend TileService
et implémentez les méthodes, comme indiqué dans l'exemple de code suivant :
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() ) }
Ajoutez ensuite un service à l'intérieur de la balise <application>
de votre fichier AndroidManifest.xml
.
<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>
Le filtre d'intent et d'autorisation enregistre ce service en tant que fournisseur de cartes.
L'icône, le libellé, la description et la ressource d'aperçu sont présentés à l'utilisateur lorsqu'il configure des cartes sur son téléphone ou sa montre.
Présentation du cycle de vie du service de cartes
Une fois que vous avez créé et déclaré votre TileService
dans le fichier manifeste de votre application, vous pouvez répondre aux modifications d'état du service de cartes.
TileService
est un service lié. Votre TileService
est lié en raison de la requête de votre application ou si le système doit communiquer avec elle. Un cycle de vie de service lié typique contient les quatre méthodes de rappel suivantes : onCreate()
, onBind()
, onUnbind()
et onDestroy()
. Le système appelle ces méthodes chaque fois que le service entre dans une nouvelle phase de cycle de vie.
En plus des rappels qui contrôlent le cycle de vie du service lié, vous pouvez implémenter d'autres méthodes spécifiques au cycle de vie de TileService
. Tous les services de cartes doivent implémenter onTileRequest()
et onTileResourcesRequest()
pour répondre aux demandes de mises à jour du système.
onTileAddEvent()
: le système n'appelle cette méthode que lorsque l'utilisateur ajoute votre carte pour la première fois et s'il la supprime, puis l'ajoute à nouveau. C'est le meilleur moment pour effectuer une initialisation ponctuelle.onTileAddEvent()
n'est appelé que lorsque l'ensemble de cartes est reconfiguré, et non chaque fois qu'une carte est créée par le système. Par exemple, lorsque l'appareil est redémarré ou allumé,onTileAddEvent()
n'est pas appelé pour les cartes déjà ajoutées. Vous pouvez utilisergetActiveTilesAsync()
à la place pour obtenir un instantané des cartes vous appartenant qui sont actives.onTileRemoveEvent()
: le système n'appelle cette méthode que si l'utilisateur supprime votre carte.onTileEnterEvent()
: le système appelle cette méthode lorsqu'une carte fournie par ce fournisseur s'affiche à l'écran.onTileLeaveEvent()
: le système appelle cette méthode lorsqu'une carte fournie par ce fournisseur disparaît de l'écran.onTileRequest()
: le système appelle cette méthode lorsqu'il demande une nouvelle timeline à ce fournisseur.onTileResourcesRequest()
: le système appelle cette méthode lorsqu'il demande un lot de ressources à ce fournisseur. Cela peut se produire lors du premier chargement d'une carte ou chaque fois que la version de la ressource change.
Interroger les cartes actives
Les tuiles actives sont des tuiles qui ont été ajoutées pour s'afficher sur la montre. Utilisez la méthode statique getActiveTilesAsync()
de TileService
pour interroger les cartes appartenant à votre application qui sont actives.
Créer une UI pour les cartes
La disposition d'une carte est écrite à l'aide d'un modèle de compilateur. La mise en page d'une carte est construite comme une arborescence constituée de conteneurs de mise en page et d'éléments de mise en page de base. Chaque élément de mise en page possède des propriétés que vous pouvez définir à l'aide de différentes méthodes setter.
Éléments de mise en page de base
Les éléments visuels suivants de la bibliothèque protolayout
sont acceptés, ainsi que les composants Material :
Text
: affiche une chaîne de texte, avec éventuellement un retour à la ligne.Image
: affiche une image.Spacer
: fournit une marge intérieure entre les éléments ou peut servir de séparateur lorsque vous définissez sa couleur d'arrière-plan.
Composants Material
Outre les éléments de base, la bibliothèque protolayout-material
fournit des composants qui garantissent une conception de carte conforme aux recommandations de l'interface utilisateur de Material Design.
Button
: composant cliquable circulaire conçu pour contenir une icône.Chip
: composant cliquable en forme de stade conçu pour contenir jusqu'à deux lignes de texte et éventuellement une icône.CompactChip
: composant cliquable en forme de stade conçu pour contenir une ligne de texte.TitleChip
: composant cliquable en forme de stade semblable àChip
, mais avec une hauteur supérieure pour accueillir le texte du titre.CircularProgressIndicator
: indicateur de progression circulaire pouvant être placé à l'intérieur d'unEdgeContentLayout
pour afficher la progression autour des bords de l'écran.
Conteneurs de mise en page
Les conteneurs suivants sont acceptés, de même que les mises en page Material :
Row
: dispose les éléments enfants horizontalement, les uns après les autres.Column
: dispose les éléments enfants verticalement, les uns après les autres.Box
: superpose les éléments enfants les uns au-dessus des autres.Arc
: dispose les éléments enfants dans un cercle.Spannable
: applique desFontStyles
spécifiques aux sections de texte, avec entrelacement du texte et des images. Pour en savoir plus, consultez Spannables.
Chaque conteneur peut comporter un ou plusieurs enfants qui peuvent, à leur tour, être des conteneurs. Par exemple, un élément Column
peut contenir plusieurs éléments Row
en tant qu'enfants, ce qui se traduit par une mise en page en forme de grille.
Par exemple, une carte avec une mise en page de conteneur et deux éléments de mise en page enfants peut se présenter comme suit :
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(); }
Mises en page Material
Outre les mises en page de base, la bibliothèque protolayout-material
fournit quelques mises en page conçues pour contenir des éléments à des "emplacements" spécifiques.
PrimaryLayout
: positionne une seule action principaleCompactChip
en bas, avec le contenu centré au-dessus.MultiSlotLayout
: positionne les libellés principaux et secondaires avec du contenu facultatif entre les deux, et unCompactChip
facultatif en bas.MultiButtonLayout
: positionne un ensemble de boutons disposés selon les directives de Material.EdgeContentLayout
: positionne le contenu autour du bord de l'écran, par exempleCircularProgressIndicator
. Lorsque vous utilisez cette mise en page, les marges et les marges intérieures appropriées sont automatiquement appliquées au contenu.
Arcs de cercle
Les conteneurs enfants Arc
suivants sont acceptés :
ArcLine
: affiche une ligne courbe autour de l'arc.ArcText
: affiche du texte incurvé dans l'arc.ArcAdapter
: affiche un élément de mise en page de base dans l'arc, tracé à une tangente par rapport à l'arc.
Pour en savoir plus, consultez la documentation de référence de chacun des types d'éléments.
Modificateurs
Des modificateurs peuvent éventuellement être appliqués à chaque élément de mise en page disponible. Utilisez ces modificateurs aux fins suivantes :
- Modifier l'apparence visuelle de la mise en page. Par exemple, ajouter un arrière-plan, une bordure ou une marge intérieure à votre élément de mise en page.
- Ajouter des métadonnées sur la mise en page. Par exemple, ajouter un modificateur de sémantique à votre élément de mise en page pour l'utiliser avec des lecteurs d'écran.
- Ajouter des fonctionnalités. Par exemple, ajouter un modificateur cliquable à votre élément de mise en page pour rendre la carte interactive. Pour en savoir plus, consultez Interagir avec les cartes.
Nous pouvons, par exemple, personnaliser l'apparence et les métadonnées par défaut d'une Image
, comme indiqué dans l'exemple de code suivant :
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
Un Spannable
est un type de conteneur spécial qui dispose les éléments de la même manière que le texte. Cela s'avère utile lorsque vous souhaitez appliquer un style différent à une seule sous-chaîne d'un bloc de texte plus grand, ce qui n'est pas possible avec l'élément Text
.
Un conteneur Spannable
est rempli d'éléments enfants Span
. Les autres éléments enfants, ou instances Spannable
imbriquées, ne sont pas autorisés.
Il existe deux types d'éléments enfants Span
:
SpanText
: affiche le texte avec un style spécifique.SpanImage
: affiche une image en l'alignant sur le texte.
Par exemple, vous pouvez mettre en italique le mot "world" dans une carte "Hello world" et insérer une image entre les mots, comme indiqué dans l'exemple de code suivant :
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(); }
Utiliser des ressources
Les cartes n'ont accès à aucune des ressources de votre application. Cela signifie que vous ne pouvez pas transmettre un ID d'image Android à un élément de mise en page Image
et vous attendre à ce qu'il soit résolu. Au lieu de cela, remplacez la méthode onTileResourcesRequest()
et fournissez des ressources manuellement.
Pour fournir des images au sein de la méthode onTileResourcesRequest()
, vous pouvez procéder de deux façons :
- Fournissez une ressource drawable à l'aide de
setAndroidResourceByResId()
. - Fournissez une image dynamique en tant que
ByteArray
à l'aide desetInlineResource()
.
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() ); }
Recommandations personnalisées
- Remarque : Le texte du lien s'affiche lorsque JavaScript est désactivé
- Migrer vers les espaces de noms ProtoLayout
ConstraintLayout
dans Compose- Créer des blocs "Réglages rapides" personnalisés pour votre application