• 12 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 01/10/2024

Organisez vos composants avec les layouts de base

Une fonction composable peut contenir divers éléments. Sans instructions précises sur leur disposition, Jetpack Compose les empile les uns sur les autres. Voyons donc comment les agencer en fonction de nos besoins. Jetpack Compose dispose de trois layouts principaux :Row,ColumnetBox. Ces layouts permettent de positionner les éléments respectivement de manière horizontale, verticale, en superposition simple ou en superposition selon l’espace disponible.

Diagramme illustrant trois types de layouts de Jetpack Compose : Column (empilement vertical), Row (empilement horizontal) et Box (superposition).

Disposez vos composants en ligne

Découvrez sa signature

Le layout Rowpermet d'aligner plusieurs composants de manière horizontale. Voici sa signature :

@Composable
fun Row(
    modifier: Modifier = Modifier,
    horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
    verticalAlignment: Alignment.Vertical = Alignment.Top,
    content: @Composable RowScope.() -> Unit
)

Concentrons-nous sur les paramètres horizontalArrangement etverticalAlignment, qui permettent de modifier l'agencement des enfants d'un layout de typeRow

Découvez le paramètre horizontalArrangement

Il spécifie la disposition horizontale des enfants. Il existe plusieurs valeurs prédéfinies dans l'objetArrangement.Horizontal, telles que :Start,End,Center,SpaceBetween,SpaceAround,SpaceEvenly, ainsi que la fonctionspacedBy().

Diagramme montrant les différentes options de disposition horizontale des enfants dans un layout Row de Jetpack Compose : Start, End, Center, SpaceBetween, SpaceAround, SpaceEvenly et spacedBy(10.dp).
Disposition des enfants au sein d’une "Row" selon la valeur du paramètre "horizontalArrangement"

Découvez le paramètre  verticalAlignment

Il détermine l'alignement vertical des enfants. Les valeurs prédéfinies dans l'objetAlignment.Vertical incluent :Top,BottometCenterVertically.

Diagramme montrant les différentes options de disposition verticale des enfants dans un layout Row de Jetpack Compose : Top, Bottom et CenterVertically.
Disposition des enfants au sein d’une "Row" selon la valeur du paramètre "verticalAlignement"

Comment cela s’applique à notre application, BestPodcast ? 

Les podcasts de notre application peuvent être divisés en plusieurs catégories. Par exemple : Technologie, Écologie et Santé. Illustrons alors comment utiliser le layoutRowen regardant l’implémentation du composantCategoryFilterpour filtrer nos podcasts. Voici le code à écrire :

@Composable
fun CategoryFilter(
    categories: List<Category>,
    selectedId: Int?,
    onCategoryClicked: (Int) -> Unit,
) {
    Row(
        modifier = Modifier.fillMaxWidth().selectableGroup(),
        horizontalArrangement = Arrangement.SpaceEvenly
    ) {
        categories.forEach { category ->
            val isSelected = (category.id == selectedId)
            Button(
                modifier =
                    Modifier.selectable(
                        selected = isSelected,
                        onClick = {
                            onCategoryClicked(category.id)
                        },
                    ),
                onClick = { onCategoryClicked(category.id) },
                colors =
                    ButtonDefaults.buttonColors(
                        containerColor = if (isSelected) {
                            MaterialTheme.colorScheme.primary
                        } else {
                            MaterialTheme.colorScheme.secondaryContainer
                        },
                        contentColor = if (isSelected) {
                            MaterialTheme.colorScheme.onPrimary
                        } else {
                            MaterialTheme.colorScheme.onSecondaryContainer
                        },
                    ),
            ) {
                if (isSelected) {
                    Icon(
                        Icons.Default.Check,
                        contentDescription = null,
                    )
                }
                Text(text = category.text)
            }
        }
    }
}

Le composantCategoryFilter utilise uneRow pour afficher les boutons horizontalement, avec un espacement égal entre chaque bouton grâce au paramètrehorizontalArrangementet à sa valeurArrangement.SpaceEvenly .Vous pouvez récupérer le code de ce composant sur GitHub, si vous souhaitez manipuler la propriétéhorizontalArrangementafin de visualiser l’impact sur l’arrangement des boutons.

Et voici à quoi ressemble le composant final :

Composant `CategoryFilter` avec pour catégories Technologie, Ecologie et Santé
Composant "CategoryFilter"

Voici une vidéo qui récapitule les principales étapes pour disposer en ligne le composantCategoryFilterde l’application “Bestpodcasts”. 

Disposez vos composants en colonne

Découvrez sa signature

Le layoutColumnpermet d'aligner plusieurs composants verticalement. Sa signature est la suivante :

@Composable
fun Column(
    modifier: Modifier = Modifier,
    verticalArrangement: Arrangement.Vertical = Arrangement.Top,
    horizontalAlignment: Alignment.Horizontal = Alignment.Start,
    content: @Composable ColumnScope.() -> Unit
)

Comme pour le layoutRow, deux paramètres permettent de spécifier la disposition des enfants verticalement ou horizontalement. Ces paramètres organisent uniformément les composants à l'intérieur d'un layout de typeColumn

Découvrez le paramètreverticalArrangement

Il définit la disposition verticale des enfants. Les valeurs prédéfinies incluentTop,Bottom,Center,SpaceBetween,SpaceAround,SpaceEvenly, ainsi que la fonctionspacedBy().

Diagramme montrant les différentes options de disposition verticale des enfants dans un layout Column de Jetpack Compose : Top, Bottom, Center, SpaceBetween, SpaceAround, SpaceEvenly et spacedBy(10.dp).
Illustration de la disposition des enfants au sein d’une "Column" selon la valeur du paramètre "verticalArrangement"

Découvrez le paramètrehorizontalAlignement

Il définit l'alignement horizontal des enfants. Les valeurs prédéfinies sont :Start,End,CenterHorizontally.

Diagramme montrant les différentes options de disposition horizontale des enfants dans un layout Column de Jetpack Compose : Start, End et CenterHorizontally.
Disposition des enfants au sein d’une "Column" selon la valeur du paramètre "horizontalAlignement"

Comment cela s’applique à notre application, BestPodcast ? 

Imaginons que l’on souhaite afficher les catégories de nos podcasts sous forme de colonne. Si on souhaite les espacer équitablement verticalement et les centrer horizontalement, le code donnerait alors :

@Composable
fun CategoryFilter(
    categories: List<Category>,
    selectedId: Int?,
    onCategoryClicked: (Int) -> Unit,
) {
    Column(
        modifier = Modifier.fillMaxWidth().selectableGroup(),
        verticalArrangement = Arrangement.SpaceEvenly,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        categories.forEach { category ->
           /*...*/
        }
    }
}

Le rendu sera alors semblable à ceci :

Les trois catégories Technologie, Écologie et Santé sont placès l'un en-dessous de l'autre.
Disposition catégorie au sein d’une "Column"

Superposez vos composants

Découvrez la signature du layoutBox

L’objectif du layoutBoxest de superposer des composants. Voici sa signature :

fun Box( 
    modifier: Modifier = Modifier, 
    contentAlignment: Alignment = Alignment.TopStart, 
    propagateMinConstraints: Boolean = false, 
    content: @Composable BoxScope.() -> Unit 
) { 
    /*...*/ 
}

Découvrez le paramètrecontentAlignement

Il sert à spécifier l'alignement commun à tous les éléments enfants de ce layout. Il existe plusieurs valeurs prédéfinies dans l'objetAlignment, notamment :Center,CenterStart,CenterEnd,TopStart,TopCenter,TopEnd,BottomStart,BottolCenter,BottomEnd.

Les valeurs sont `Center`, `CenterStart`, `CenterEnd`, `TopStart`, `TopCenter`, `TopEnd`, `BottomStart`, `BottomCenter` et `BottomEnd`
Disposition des enfants au sein d’une "Box" selon la valeur du paramètre "contentAlignement"

Comment cela s’applique à notre application, BestPodcast ?

Prenons comme exemple le composant ci-dessous, qui consiste en la superposition du logo d’un podcast, avec une image statique représentant une onde sonore. Nous appellerons ce composantHighlightedLogo . Pour réaliser ce composant, l’usage du layoutBoxest nécessaire. Le code de ce composant est le suivant : 

@Composable
private fun HighlightedLogo(
    logoUrl: String,
    contentDescription: String?,
) {
    Box(
        contentAlignment = Alignment.Center,
    ) {
        Image(
            painter = painterResource(id = R.drawable.soundwave),
            contentDescription = null,
            colorFilter =
                ColorFilter.tint(
                    color = MaterialTheme.colorScheme.primary,
                ),
            modifier = Modifier.fillMaxWidth(),
        )
        AsyncImage(
            model = logoUrl,
            contentDescription = contentDescription,
            placeholder = painterResource(id = R.drawable.placeholder),
            modifier =
                Modifier
                   .fillMaxWidth(fraction = 0.6f)
                    .aspectRatio(1f)
                    .padding(8.dp),
        )
    }
}

En analysant ce code, vous devriez remarquer les points suivants :

  • Les enfants du layoutBoxse superposent dans l’ordre dans lequel ils sont écrits dans le code. Ainsi, si vous inversez l’ordre en mettant le composantAsyncImagedu logo avant l’imagesoundwave, alors le logo sera partiellement masqué par l’onde.

  • L’usage du paramètrecontentAlignmentavec la valeurAlignment.Center, permet de centrer les éléments.

Voici le résultat.

Le composant `HighlightedLogo`est placé par-dessus un fond qui représente les ondes d'un podcast.
Illustration du composant "HighlightedLogo"

Voici une vidéo qui récapitule les principales étapes pour supperposer vos composants.

À vous de jouer !

Contexte

Il est grand temps de peaufiner l’agencement des éléments constituant notre composantPodcastItem, puis d’intégrer la notion de catégorie de podcast que nous venons de voir. Voici les consignes que Charlie vous a transmises. 

Consignes

  1. Modifiez le composantPodcastItemafin de centrer verticalement les éléments qu’il contient. 

  2. Espacez chaque élément du composantPodcastItemde8.dp

  3. Intégrez la notion de catégorie au sein de l’objetPodcastet de laPodcastFactory. Vous pouvez pour cela récupérer le code sur GitHub.

  4. Affichez la catégorie sous le titre du podcast, en utilisant le bon layout. Le texte de la catégorie doit être de la couleurtertiaryde votre thème, écrit en italique et avec le stylelabelSmall.

  5. Superposez au logo du podcast une icône permettant d’indiquer visuellement qu’il s’agit d’un podcast avec les spécifications suivantes : 

  • Utiliser l’icône MaterialIcons.Default.Podcasts.

  • Celle-ci doit faire24.dp en hauteur et largeur.

  • Elle doit être positionnée en bas à droite du logo.

  • Elle doit avoir une teinte et une couleur de fond issue du thème Material.

  • Son bord inférieur droit doit être arrondi, pour épouser la forme du logo (utilisez pour cela le Modifierclipet la classeRoundedCornerShape).

Livrables

Votre projet sur Android Studio doit être conforme aux consignes ci-dessus.

En résumé

  • Les layouts principaux de Jetpack Compose sontRow,ColumnetBox .

  • Rowpermet d’organiser globalement ses enfants horizontalement et verticalement grâce aux paramètreshorizontalArrangementetverticalAlignment.

  • Columnpermet d’organiser globalement ses enfants verticalement et horizontalement grâce aux paramètresverticalArrangementethorizontalAlignment.

  • Boxpermet d’aligner globalement ses enfants grâce au paramètrecontentAlignment.

Nous avons appris à structurer nos composants grâce aux layoutsRow,ColumnetBox. Nous avons également vu comment organiser et aligner leurs enfants de manière globale. Il est maintenant temps d’aller un peu plus loin en optimisant et améliorant l’organisation de ces composants.

Exemple de certificat de réussite
Exemple de certificat de réussite