Atelier de programmation sur Compose pour Wear OS

1. Introduction

11ba5a682f1ffca3.png

Compose pour Wear OS vous permet de transposer à des accessoires connectés les connaissances que vous avez acquises en créant des applications à l'aide de Jetpack Compose.

Avec l'intégration de Material You, Compose pour Wear OS simplifie et accélère le développement d'UI. Vous pouvez ainsi créer de superbes applications avec moins de code.

Pour cet atelier de programmation, nous partons du principe que vous possédez quelques bases sur Compose, sans avoir besoin d'être expert en la matière.

Vous allez créer plusieurs composables (simples et complexes) spécifiques à Wear OS, afin qu'à la fin vous puissiez commencer à écrire vos propres applications pour Wear OS. Voyons cela plus en détail.

Points abordés

  • Similitudes et différences par rapport à ce que vous faisiez auparavant avec Compose
  • Composables simples et leur fonctionnement sur Wear OS
  • Composables propres à Wear OS
  • LazyColumn de Wear OS (ScalingLazyColumn)
  • Version de Scaffold de Wear OS

Ce que vous allez créer

Vous allez créer une application simple qui affiche une liste déroulante de composables optimisés pour Wear OS.

En utilisant Scaffold, vous aurez également l'heure affichée de façon incurvée en haut, une vignette et un indicateur de défilement ancré sur un côté de l'appareil.

Voici comment cela se présentera à la fin de l'atelier de programmation :

31cb08c0fa035400.gif

Conditions préalables

2. Configuration

Au cours de cette étape, vous allez configurer votre environnement et télécharger le projet d'initiation.

Ce dont vous avez besoin

Télécharger le code

Si git est installé, vous pouvez simplement exécuter la commande ci-dessous pour cloner le code à partir de ce dépôt. Pour vérifier s'il est installé, saisissez git --version dans le terminal ou la ligne de commande, et vérifiez qu'il fonctionne correctement.

git clone https://github.com/android/codelab-compose-for-wear-os.git
cd compose-for-wear-os

Si vous n'avez pas git, cliquez sur le bouton ci-dessous pour télécharger l'ensemble du code de cet atelier de programmation :

Télécharger le fichier ZIP

À tout moment, vous pouvez exécuter l'un ou l'autre de ces modules dans Android Studio en modifiant la configuration d'exécution dans la barre d'outils.

400c194c8948c952.png

Ouvrir un projet dans Android Studio

  1. Dans la fenêtre "Welcome to Android Studio" (Bienvenue dans Android Studio), sélectionnez 61d0a4432ef6d396.png Open an existing Project (Ouvrir un projet existant).
  2. Sélectionnez le dossier [Download Location].
  3. Une fois qu'Android Studio a importé le projet, vérifiez que vous pouvez exécuter les modules start et finished sur un appareil physique ou un émulateur Wear OS.
  4. Le module start doit ressembler à la capture d'écran ci-dessous. C'est dans cet espace que vous allez travailler.

c82b07a089099c4f.png

Se familiariser avec le code de démarrage

  • build.gradle contient la configuration de base d'une application. Il inclut les dépendances nécessaires à la création d'une application Wear OS avec des composables. Nous verrons les similitudes et différences entre Jetpack Compose et la version Wear OS.
  • main > AndroidManifest.xml contient les éléments nécessaires à la création d'une application Wear OS. Nous ne reviendrons pas dessus, car c'est identique à une application non Compose et semblable à une application mobile.
  • Le dossier main > theme/ contient les fichiers Color, Type et Theme qu'utilise Compose pour le thème.
  • main > MainActivity.kt contient le code récurrent pour créer une application avec Compose. Il inclut également les composables de premier niveau (tels que Scaffold et ScalingLazyList) pour notre application.
  • main > ReusableComponents.kt contient les fonctions de la plupart des composables spécifiques à Wear que nous allons créer. Une grande partie de ce que nous allons faire le sera dans ce fichier.

3. Examiner les dépendances

La plupart des modifications que vous apporterez aux dépendances liées à Wear figureront dans les couches d'architecture supérieures (voir encadré rouge ci-dessous).

d64d9c262a79271.png

Autrement dit, bon nombre des dépendances que vous utilisez déjà avec Jetpack Compose ne changeront pas pour Wear OS. Par exemple, les dépendances de l'UI, de l'environnement d'exécution, du compilateur et des animations resteront les mêmes.

Toutefois, vous devez utiliser les bibliothèques Material, Foundation et Navigation appropriées de Wear OS, lesquelles sont différentes de celles que vous avez utilisées auparavant.

Vous trouverez ci-dessous un comparatif qui montre clairement les différences :

Dépendance Wear OS (androidx.wear.*)

Comparatif

Dépendance standard (androidx.*)

androidx.wear.compose:compose-material

au lieu de

androidx.compose.material:material

androidx.wear.compose:compose-navigation

au lieu de

androidx.navigation:navigation-compose

androidx.wear.compose:compose-foundation

en plus de

androidx.compose.foundation:foundation

androidx.wear.compose:compose-ui-tooling

en plus de

androidx.compose.ui:ui-tooling-preview

1. Les développeurs peuvent continuer à utiliser d'autres bibliothèques liées à Material, comme l'ondulation et les icônes Material, qui sont étendues avec la bibliothèque Wear Compose Material.

Ouvrez build.gradle, puis recherchez TODO: Review Dependencies dans le module start (cette étape vise à examiner les dépendances ; vous n'ajouterez aucun code ici).

start/build.gradle :

// TODO: Review Dependencies
// General Compose dependencies
implementation "androidx.activity:activity-compose:$activity_compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation "androidx.compose.foundation:foundation:$compose_version"
implementation "androidx.compose.material:material-icons-extended:$compose_version"

// Compose for Wear OS Dependencies
implementation "androidx.wear.compose:compose-material:$wear_compose_version"

// Foundation is additive, so you can use the standard version in your Wear OS app.
implementation "androidx.wear.compose:compose-foundation:$wear_compose_version"

// Compose preview annotations for Wear OS.
implementation "androidx.wear.compose:compose-ui-tooling:$wear_compose_version"

Comme vous devriez reconnaître bon nombre des dépendances générales de Compose, nous n'allons pas nous y attarder.

Passons aux dépendances Wear OS.

Comme indiqué précédemment, seule la version de material spécifique à Wear OS (androidx.wear.compose:compose-material) est incluse. Autrement dit, vous ne verrez pas ou n'ajouterez pas androidx.compose.material:material dans votre projet.

Il est important de préciser que vous pouvez utiliser d'autres bibliothèques Material avec Wear Material. C'est d'ailleurs ce que nous faisons dans cet atelier en incluant androidx.compose.material:material-icons-extended.

Enfin, nous incluons la bibliothèque additionnelle Wear foundation pour Compose (androidx.wear.compose:compose-foundation), qui peut s'utiliser avec la foundation standard que vous avez déjà utilisée. En fait, vous avez probablement déjà vu que nous l'avons ajoutée aux dépendances générales de Compose.

Maintenant que nous avons examiné les dépendances, penchons-nous sur l'application principale.

4. Examiner MainActivity

Nous allons travailler exclusivement dans le module

start

Assurez-vous que chaque fichier que vous ouvrez s'y trouve bien.

Commençons par ouvrir MainActivity dans le module start.

Il s'agit d'une classe assez simple qui étend ComponentActivity et utilise setContent { WearApp() } pour créer l'UI.

Compte tenu de vos connaissances concernant Compose, cela devrait vous sembler familier. Nous configurons simplement l'UI.

Faites défiler le code vers le bas jusqu'à la fonction modulable WearApp(). Avant de parler du code lui-même, précisons que vous allez y voir un certain nombre de "TODO" placés à différents endroits. Chacun représente des étapes de cet atelier de programmation. Pour l'instant, vous pouvez les ignorer.

Exemple :

Code dans WearApp() :

WearAppTheme {
    // TODO: Swap to ScalingLazyListState
    val listState = rememberLazyListState()

    /* *************************** Part 4: Wear OS Scaffold *************************** */
    // TODO (Start): Create a Scaffold (Wear Version)

        // Modifiers used by our Wear composables.
        val contentModifier = Modifier.fillMaxWidth().padding(bottom = 8.dp)
        val iconModifier = Modifier.size(24.dp).wrapContentSize(align = Alignment.Center)

        /* *************************** Part 3: ScalingLazyColumn *************************** */
        // TODO: Create a ScalingLazyColumn (Wear's version of LazyColumn)
        LazyColumn(
            modifier = Modifier.fillMaxSize(),
            contentPadding = PaddingValues(
                top = 32.dp,
                start = 8.dp,
                end = 8.dp,
                bottom = 32.dp
            ),
            verticalArrangement = Arrangement.Center,
            state = listState
        ) {

            // TODO: Remove item; for beginning only.
            item { StartOnlyTextComposables() }

            /* ******************* Part 1: Simple composables ******************* */
            item { ButtonExample(contentModifier, iconModifier) }
            item { TextExample(contentModifier) }
            item { CardExample(contentModifier, iconModifier) }

            /* ********************* Part 2: Wear unique composables ********************* */
            item { ChipExample(contentModifier, iconModifier) }
            item { ToggleChipExample(contentModifier) }
        }

    // TODO (End): Create a Scaffold (Wear Version)

}

Commençons par définir le thème WearAppTheme { } (exactement comme vous l'avez écrit précédemment, c'est-à-dire que vous avez défini un MaterialTheme avec des couleurs, une typographie et des formes).

Toutefois, dans le cas de Wear OS, nous recommandons généralement d'utiliser les formes Material Wear par défaut, lesquelles sont optimisées à la fois pour les appareils ronds et ceux d'une autre forme. Ainsi, si vous consultez theme/Theme.kt, vous pouvez voir que nous ne remplaçons pas les formes.

Si vous le souhaitez, vous pouvez ouvrir theme/Theme.kt pour l'étudier plus en détail, mais, une fois encore, sachez que c'est pareil qu'avant.

Nous allons maintenant créer des modificateurs pour les composables Wear que nous allons développer. Il n'est donc pas nécessaire de les spécifier à chaque fois. Il s'agit principalement de centrer le contenu et d'ajouter une marge intérieure.

Nous allons ensuite créer une LazyColumn afin d'obtenir une liste à défilement vertical pour un ensemble d'éléments (tout comme vous faisiez auparavant).

Code :

item { StartOnlyTextComposables() }

/* ******************* Part 1: Simple composables ******************* */
item { ButtonExample(contentModifier, iconModifier) }
item { TextExample(contentModifier) }
item { CardExample(contentModifier, iconModifier) }

/* ********************* Part 2: Wear unique composables ********************* */
item { ChipExample(contentModifier, iconModifier) }
item { ToggleChipExample(contentModifier) }

Pour les éléments eux-mêmes, seul StartOnlyTextComposables() génère une UI. (Nous compléterons le reste tout au long de l'atelier de programmation.)

En fait, ces fonctions se trouvent dans le fichier ReusableComponents.kt, que nous verrons dans la section suivante.

Commençons maintenant à utiliser Compose pour Wear OS !

5. Ajouter des composables simples

Nous commencerons avec trois composables (Button, Text et Card) que vous connaissez probablement déjà.

Tout d'abord, nous allons supprimer le composable "hello world".

Recherchez TODO: Remove item, puis effacez le commentaire et la ligne située juste en dessous :

Étape 1

// TODO: Remove item; for beginning only.
item { StartOnlyTextComposables() }

Ajoutons à présent notre premier composable.

Créer un composable Button

Ouvrez ReusableComponents.kt dans le module start, puis recherchez TODO: Create a Button Composable et remplacez la méthode composable actuelle par ce code.

Étape 2

// TODO: Create a Button Composable (with a Row to center)
@Composable
fun ButtonExample(
    modifier: Modifier = Modifier,
    iconModifier: Modifier = Modifier
) {
    Row(
        modifier = modifier,
        horizontalArrangement = Arrangement.Center
    ) {
        // Button
        Button(
            modifier = Modifier.size(ButtonDefaults.LargeButtonSize),
            onClick = { /* ... */ },
        ) {
            Icon(
                imageVector = Icons.Rounded.Phone,
                contentDescription = "triggers phone action",
                modifier = iconModifier
            )
        }
    }
}

La fonction modulable ButtonExample() (où figure ce code) va désormais générer un bouton centré.

Examinons le code.

Row ne sert ici qu'à centrer le composable Button sur l'écran de forme ronde. Vous pouvez voir que nous faisons cela en appliquant le modificateur que nous avons créé dans MainActivity et en le transmettant à cette fonction. Plus tard, quand nous ferons défiler l'écran d'un appareil rond, nous chercherons à nous assurer que le contenu n'est pas tronqué (raison pour laquelle il est centré).

Nous allons ensuite créer le Button lui-même. C'est le même code que celui que vous auriez utilisé auparavant pour un bouton, mais dans le cas présent, nous allons utiliser ButtonDefault.LargeButtonSize. Veillez à utiliser ces tailles prédéfinies, car elles sont optimisées pour des appareils Wear OS.

Attribuons ensuite l'événement de clic à une expression lambda vide. Dans notre cas, ces composables servent juste à une démonstration. Nous n'en aurons pas besoin. Toutefois, dans une application réelle, nous communiquerions, par exemple, avec un ViewModel pour exécuter la logique métier.

Nous allons maintenant attribuer une icône à notre bouton. Ce code est le même que celui que vous avez vu avant pour une Icon. Nous récupérons également l'icône dans la bibliothèque androidx.compose.material:material-icons-extended.

Enfin, nous allons spécifier le modificateur que nous avons défini précédemment pour les icônes.

Si vous exécutez l'application, vous devriez obtenir un résultat semblable à celui-ci :

c9b981101ae653db.png

Il s'agit d'un code que vous avez probablement déjà écrit (ce qui est très bien). La différence est que vous disposez désormais d'un bouton optimisé pour Wear OS.

Prenons un autre exemple simple.

Créer un composable Text

Dans ReusableComponents.kt, recherchez TODO: Create a Text Composable et remplacez la méthode composable actuelle par ce code.

Étape 3

// TODO: Create a Text Composable
@Composable
fun TextExample(modifier: Modifier = Modifier) {
    Text(
        modifier = modifier,
        textAlign = TextAlign.Center,
        color = MaterialTheme.colors.primary,
        text = stringResource(R.string.device_shape)
    )
}

Nous allons créer le composable Text, définir son modificateur, aligner le texte, choisir une couleur, puis spécifier le texte lui-même à partir d'une ressource de chaîne.

Les composables Text devraient sembler très familiers aux développeurs Compose, et le code est identique à celui que vous avez utilisé auparavant.

Voyons le résultat :

b33172e992d1ea3e.png

La fonction composable TextExample() (à l'endroit où nous avons placé notre code) génère désormais un composable Text dans notre couleur Material principale.

La chaîne est tirée du fichier res/values/strings.xml. En fait, si vous consultez le dossier res/values, vous devriez voir deux fichiers de ressources strings.xml.

Wear OS fournit des ressources de chaîne pour les appareils ronds et ceux d'une autre forme. Par conséquent, si nous l'exécutons sur un émulateur carré, la chaîne changera :

2e7b20dbfbd23350.png

Jusque-là, tout va bien. Voyons notre dernier composable similaire : Card.

Créer un composable Card

Dans ReusableComponents.kt, recherchez TODO: Create a Card et remplacez la méthode composable actuelle par ce code.

Étape 4

// TODO: Create a Card (specifically, an AppCard) Composable
@Composable
fun CardExample(
    modifier: Modifier = Modifier,
    iconModifier: Modifier = Modifier
) {
    AppCard(
        modifier = modifier,
        appImage = {
            Icon(
                imageVector = Icons.Rounded.Message,
                contentDescription = "triggers open message action",
                modifier = iconModifier
            )
        },
        appName = { Text("Messages") },
        time = { Text("12m") },
        title = { Text("Kim Green") },
        onClick = { /* ... */ }
    ) {
        Text("On my way!")
    }
}

Wear est un peu différent, car nous avons deux fiches principales : AppCard et TitleCard.

Dans le cas présent, nous voulons ajouter une Icon dans notre fiche. Nous allons donc utiliser AppCard. (TitleCard contient moins d'emplacements. Pour en savoir plus, consultez le guide des fiches.)

Nous allons créer le composable AppCard, définir son modificateur, ajouter une Icon et plusieurs paramètres composables Text (chacun à une place différente sur la fiche), puis spécifier le texte principal du contenu à la fin.

Voyons le résultat :

1fc761252ac5b466.png

À ce stade, vous constaterez probablement que, pour ces composables, le code Compose est presque identique à celui que vous avez utilisé auparavant, ce qui est plutôt bien, non ? Vous allez pouvoir réutiliser toutes ces connaissances que vous avez déjà acquises.

Voyons maintenant de nouveaux composables.

6. Ajouter des composables Wear uniques

Dans cette section, nous allons étudier les composables Chip et ToggleChip.

Créer un composable Chip

Les chips sont en fait spécifiés dans les consignes Material, mais il n'y a aucune fonction modulable réelle dans la bibliothèque Material standard.

Ils sont censés être des actions rapides en un geste, ce qui est plutôt logique pour un appareil Wear où l'espace d'affichage est limité.

Voici quelques variantes de la fonction composable Chip pour vous donner une idée de ce que vous pouvez créer :

Passons à l'écriture du code.

Dans ReusableComponents.kt, recherchez TODO: Create a Chip et remplacez la méthode composable actuelle par ce code.

Étape 5

// TODO: Create a Chip Composable
@Composable
fun ChipExample(
    modifier: Modifier = Modifier,
    iconModifier: Modifier = Modifier
) {
    Chip(
        modifier = modifier,
        onClick = { /* ... */ },
        label = {
            Text(
                text = "5 minute Meditation",
                maxLines = 1,
                overflow = TextOverflow.Ellipsis
            )
        },
        icon = {
            Icon(
                imageVector = Icons.Rounded.SelfImprovement,
                contentDescription = "triggers meditation action",
                modifier = iconModifier
            )
        },
    )
}

Le composable Chip utilisant de nombreux paramètres identiques à ceux que vous avez l'habitude d'utiliser avec d'autres composables (modificateur et onClick), nous n'avons donc pas besoin de les revoir.

Il comporte également un libellé (pour lequel nous créons un composable Text) et une icône.

Le code Icon devrait être entièrement identique à celui que vous avez vu dans les autres composables. Toutefois, pour celui-ci, nous récupérons l'icône Self Improvement dans la bibliothèque androidx.compose.material:material-icons-extended.

Voyons comment cela se présente (pensez à faire défiler l'écran vers le bas) :

d97151e85e9a1e03.png

Très bien. Voyons une variante de Toggle : le composable ToggleChip.

Créer un composable ToggleChip

ToggleChip est identique à Chip, mais permet à l'utilisateur d'interagir avec une case d'option, un bouton d'activation ou une case à cocher.

Dans ReusableComponents.kt, recherchez TODO: Create a ToggleChip et remplacez la méthode composable actuelle par ce code.

Étape 6

// TODO: Create a ToggleChip Composable
@Composable
fun ToggleChipExample(modifier: Modifier = Modifier) {
    var checked by remember { mutableStateOf(true) }
    ToggleChip(
        modifier = modifier,
        checked = checked,
        toggleControl = {
            Switch(
                checked = checked,
                modifier = Modifier.semantics {
                    this.contentDescription = if (checked) "On" else "Off"
                }
            )
        },
        onCheckedChange = {
            checked = it
        },
        label = {
            Text(
                text = "Sound",
                maxLines = 1,
                overflow = TextOverflow.Ellipsis
            )
        }
    )
}

Désormais, la fonction composable ToggleChipExample() (où figure ce code) génère un ToggleChip utilisant un bouton bascule (au lieu d'une case à cocher ou d'une case d'option).

Commençons par créer un MutableState. Nous ne l'avons pas fait dans les autres fonctions, car le but des démonstrations d'UI est que vous puissiez voir ce que propose Wear.

Dans une application normale, vous voudriez probablement transmettre l'état coché et l'expression lambda pour gérer le geste de sorte que le composable puisse être sans état (en savoir plus).

Dans le cas présent, nous simplifions les choses afin de montrer à quoi ressemble ToggleChip en action avec un bouton d'activation qui fonctionne (même si nous ne faisons rien avec l'état).

Définissons ensuite le modificateur, l'état coché et la commande du bouton d'activation pour obtenir le bouton bascule souhaité.

Créons maintenant une expression lambda pour changer l'état et spécifions le libellé avec un composable Text (et quelques paramètres de base).

Voyons le résultat :

ea1a76abd54877b.png

OK. Vous avez maintenant vu de nombreux composables spécifiques à Wear OS et, comme indiqué précédemment, la majeure partie du code est presque identique à celui que vous avez écrit auparavant.

Voyons à présent quelque chose d'un peu plus élaboré.

7. Migrer vers ScalingLazyColumn

Vous avez probablement utilisé LazyColumn dans vos applications mobiles pour obtenir une liste à défilement vertical.

Un appareil rond étant plus petit en haut et en bas, il y a moins de place pour afficher les éléments. C'est pourquoi Wear OS possède sa propre version de LazyColumn pour mieux prendre en charge ce type d'appareil.

ScalingLazyColumn étend LazyColumn pour accepter à la fois la mise à l'échelle et la transparence en haut et en bas de l'écran, afin de rendre le contenu plus lisible pour l'utilisateur.

Voici une démonstration :

198ee8e8fa799f08.gif

Notez qu'à mesure que l'élément se rapproche du centre, il s'agrandit jusqu'à atteindre sa taille maximale, et que lorsqu'il s'éloigne, il rétrécit (tout en étant plus transparent).

Voici un exemple plus concret à partir d'une application :

a5a83ab2e5d5230f.gif

Nous avons constaté que c'était nettement plus lisible.

Maintenant que vous avez vu ScalingLazyColumn en action, nous pouvons commencer à convertir notre LazyColumn.

Convertir en un ScalingLazyListState

Dans MainActivity.kt, recherchez TODO: Swap to ScalingLazyListState, puis remplacez ce commentaire et la ligne ci-dessous par ce code.

Étape 7

// TODO: Swap to ScalingLazyListState
val listState = rememberScalingLazyListState()

Les noms sont presque identiques, hormis la partie "Scaling". Tout comme LazyListState gère l'état d'une LazyColumn, ScalingLazyListState le gère pour une ScalingLazyColumn.

Convertir en une ScalingLazyColumn

Passons maintenant à ScalingLazyColumn.

Dans MainActivity.kt, recherchez "TODO: Swap a ScalingLazyColumn". Commencez par remplacer LazyColumn par ScalingLazyColumn.

Supprimez ensuite contentPadding et verticalArrangement. ScalingLazyColumn fournit déjà les paramètres par défaut qui garantissent un meilleur effet visuel par défaut, car la majorité de la fenêtre d'affichage sera composée d'une liste d'éléments. Dans de nombreux cas, les paramètres par défaut sont suffisants. Si vous disposez d'un en-tête, nous vous recommandons de le placer en premier dans ListHeader. Sinon, définissez autoCentering avec itemIndex ayant une valeur de 0 pour garantir une marge intérieure suffisante pour le premier élément.

Étape 8

// TODO: Swap a ScalingLazyColumn (Wear's version of LazyColumn)
ScalingLazyColumn(
    modifier = Modifier.fillMaxSize(),
    autoCentering = AutoCenteringParams(itemIndex = 0),
    state = listState

Et voilà ! Voyons le résultat :

5c25062081307944.png

Comme vous pouvez le constater, le contenu est mis à l'échelle, et la transparence est ajustée en haut comme en bas de l'écran au fur et à mesure que vous faites défiler. Cela s'effectue très facilement.

Vous pouvez encore mieux voir avec les composables de méditation quand vous déplacez le contenu vers le haut et vers le bas.

Passons maintenant au dernier point : le Scaffold de Wear OS.

8. Ajouter un échafaudage

Scaffoldfournit une structure de disposition qui vous permet d'organiser les écrans selon des schémas courants, comme sur un mobile. Mais plutôt que d'avoir une barre d'application, un bouton d'action flottant, un panneau ou tout autre élément spécifique aux mobiles, l'échafaudage (scaffolding) prend en charge quatre dispositions propres à Wear avec des composants de premier niveau : heure, vignette, indicateur de défilement/position et indicateur de page.

Il est également compatible avec les appareils ronds et ceux d'une autre forme.

Voici comment cela se présente :

TimeText

Vignette

PositionIndicator

PageIndicator

Nous allons examiner les trois premiers composants, mais avant tout, mettons l'échafaudage en place.

Ajouter un échafaudage

Ajoutons maintenant le code récurrent pour Scaffold.

Recherchez TODO (Start): Create a Scaffold (Wear Version) et ajoutez le code en dessous.

Étape 9

// TODO (Start): Create a Scaffold (Wear Version)
Scaffold(
    timeText = { },
    vignette = { },
    positionIndicator = { }
) {

Nous détaillerons chacun de ces paramètres dans l'ordre lors des prochaines étapes. Pour l'instant, nous ne créons aucune UI.

Assurez-vous ensuite d'ajouter l'accolade fermante au bon endroit. Recherchez TODO (End): Create a Scaffold (Wear Version) et ajoutez-y l'accolade :

Étape 10

// TODO (End): Create a Scaffold (Wear Version)
}

Commençons par l'exécuter. Le résultat devrait se présenter comme suit :

ff554156bbe03abb.png

Notez que le résultat n'est pas vraiment différent d'avant depuis que nous avons ajouté l'échafaudage. Toutefois, cela changera quand nous commencerons à intégrer nos composants.

Commençons par le premier des trois paramètres : TimeText.

TimeText

TimeText utilise un texte incurvé qui offre aux développeurs un moyen simple d'afficher l'heure sans avoir à placer le composable ni à effectuer quoi que ce soit au niveau des classes associées à l'heure.

Selon les consignes Material, il est recommandé d'afficher l'heure en haut de n'importe quel écran de l'application. Exemple :

2a642b9ff3334e2a.png

L'ajout de TimeText est en fait relativement simple.

Repérez timeText = { }, et remplacez-le par le code ci-dessous :

Étape 11

timeText = {
    TimeText(modifier = Modifier.scrollAway(listState))
},

Commençons par créer un composable TimeText. Nous pourrions ajouter d'autres paramètres pour insérer du texte avant et/ou après l'heure, mais nous préférons rester dans la simplicité.

Lors de la création de TimeText avec des éléments à faire défiler tels que des listes, TimeText doit disparaître en fondu à mesure que l'utilisateur commence à faire défiler une liste d'éléments vers le haut. Pour cela, nous ajoutons Modifier.scrollAway qui fera défiler TimeText verticalement ou en dehors du champ de vision, en fonction de l'état du défilement.

Essayez de l'exécuter. Vous devriez maintenant voir l'heure, mais si vous faites défiler l'écran, elle disparaît.

43e90952cbcce9b0.png

Nous allons ensuite aborder la Vignette.

Ajouter une vignette (ou un effet vignetage)

Une Vignette floute les bords supérieur et inférieur quand l'écran affiché de l'accessoire connecté peut être déroulé.

Les développeurs peuvent choisir de flouter le haut, le bas ou les deux, selon le cas d'utilisation.

Exemple :

7e85451de59e1d0.png

Nous n'avons qu'un seul écran (qu'il est possible de faire défiler), et nous voulons afficher la vignette pour une meilleure lisibilité. Alors allons-y.

Repérez vignette = { }, et remplacez-le par le code ci-dessous :

Étape 12

vignette = {
    // Only show a Vignette for scrollable screens. This code lab only has one screen,
    // which is scrollable, so we show it all the time.
    Vignette(vignettePosition = VignettePosition.TopAndBottom)
},

Lisez le commentaire pour savoir plus en détail quand afficher ou non une vignette. Dans le cas présent, nous voulons qu'elle soit affichée tout le temps, et nous voulons flouter le haut et le bas de l'écran.

f4679e75e295642c.png

Si vous regardez en haut ou en bas (en particulier sur les composables violets), vous devriez voir l'effet.

Terminons maintenant par le dernier paramètre de Scaffold : PositionIndicator.

Ajouter PositionIndicator

PositionIndicator (appelé également "indicateur de défilement") est un indicateur situé sur la partie droite de l'écran visant à montrer la position actuelle de l'indicateur en fonction du type d'objet d'état que vous avez transmis. En ce qui nous concerne ici, il s'agit de ScalingLazyListState.

Exemple :

ba42dce6b62e720f.png

Vous vous demandez peut-être pourquoi l'indicateur de position doit être situé au niveau de Scaffold et non au niveau de la ScalingLazyColumn.

En fait, compte tenu de la courbure de l'écran, l'indicateur de position doit être centré sur la montre (Scaffold) et pas simplement sur la fenêtre d'affichage (ScalingLazyColumn). Sinon, il risquerait d'être tronqué.

Par exemple, dans l'application ci-dessous, nous pouvons supposer que le composable "Playlist" ne fait pas partie de la zone déroulante. L'indicateur de position est centré sur la ScalingLazyColumn, mais il n'occupe pas la totalité de l'écran. Vous pouvez ainsi voir qu'une grande partie est tronquée.

8018e75f709e25a0.png

Toutefois, si nous centrons l'indicateur de position sur toute la surface visible (ce que permet Scaffold), vous pouvez maintenant le voir clairement.

1a82be61163ead86.png

Autrement dit, PositionIndicator exige que ScalingLazyListState (compte tenu de la position dans la liste déroulante) soit au-dessus de Scaffold.

Si vous êtes très observateur, vous avez peut-être remarqué que nous avons déjà placé ScalingLazyListState au-dessus de Scaffold pour masquer ou afficher l'heure. Dans notre cas, le travail est donc terminé.

Maintenant que nous avons vu pourquoi l'indicateur de position devrait se trouver dans l'échafaudage, ajoutons-le à notre application.

Repérez positionIndicator = { } et remplacez-le par le code ci-dessous :

Étape 12

positionIndicator = {
    PositionIndicator(
        scalingLazyListState = listState
    )
}

C'est assez simple, PositionIndicator nécessite l'état de défilement pour s'afficher correctement, ce qui est désormais possible.

Il possède aussi une fonctionnalité intéressante qui le masque quand l'utilisateur ne fait pas défiler l'écran.

Nous utilisons ScalingLazyListState, mais PositionIndicator offre de nombreuses autres options de défilement (comme ScrollState et LazyListState) et peut même gérer le bouton latéral rotatif ou

le contour rotatif. Pour voir toutes les options, consultez le fichier KDocs pour chaque version.

Voyons maintenant comment cela se présente :

cfcbd3003744a6d.png

Essayez de faire défiler l'écran vers le haut et vers le bas. Vous ne devriez voir apparaître l'indicateur de défilement que lorsque vous faites défiler l'écran.

Bravo ! Vous avez terminé la démonstration d'UI pour la plupart des composables Wear OS.

9. Félicitations

Félicitations ! Vous avez appris les principes de base pour utiliser Compose sur Wear OS.

Vous pouvez maintenant transposer toutes vos connaissances sur Compose pour créer de superbes applications Wear OS.

Et maintenant ?

Consultez les autres ateliers de programmation Wear OS :

Complément d'informations

Commentaires

Votre avis nous intéresse. Partagez vos expériences avec Compose pour Wear OS et ce que vous pouvez créer ! Rejoignez la discussion sur le canal #compose-wear de Kotlin Slack et continuez à partager vos commentaires sur notre issue tracker.

À vous de jouer !