1. Avant de commencer
Material Design est un système de conception conçu et entretenu par des concepteurs et des développeurs de Google pour créer des expériences numériques de haute qualité pour Android, ainsi que pour d'autres plates-formes mobiles et Web. Vous y trouverez des consignes vous expliquant comment élaborer une application à l'interface lisible, attrayante et cohérente.
Dans cet atelier de programmation, vous allez apprendre à utiliser la thématisation Material, qui vous permet d'utiliser Material Design dans votre application, et découvrirez comment personnaliser les couleurs, la typographie et les formes. Vous pouvez personnaliser votre application autant que vous le souhaitez. Vous allez également apprendre à ajouter une barre d'application supérieure pour afficher le nom et l'icône de l'application.
Conditions préalables
- Vous connaissez les bases du langage de programmation Kotlin, y compris la syntaxe, les fonctions et les variables.
- Vous savez créer des mises en page dans Compose, y compris des lignes et des colonnes avec marge intérieure.
- Vous savez créer des listes simples dans Compose.
Points abordés
- Appliquer la thématisation Material à une application Compose.
- Ajouter une palette de couleurs personnalisée à votre application.
- Ajouter des polices personnalisées à votre application.
- Ajouter des formes personnalisées aux éléments de votre application.
- Ajouter une barre d'application supérieure à votre application.
Objectifs de l'atelier
- Vous allez créer une application attrayante qui respecte les bonnes pratiques Material Design.
Ce dont vous avez besoin
- La dernière version d'Android Studio.
- Une connexion Internet pour télécharger le code de démarrage et les polices.
2. Présentation de l'application
Dans cet atelier de programmation, vous allez créer Woof, une application qui affiche une liste de chiens et utilise Material Design pour créer une expérience attractive dans l'application.
Dans cet atelier de programmation, nous vous présenterons les possibilités offertes par la thématisation Material. Vous découvrirez également comment cette méthode pour améliorer l'apparence de vos prochaines applications.
Palette de couleurs
Vous trouverez ci-dessous les palettes de couleurs des thèmes clair et sombre que nous allons créer.
Voici la version finale de l'application avec les deux thèmes.
Thème clair | Thème sombre |
Typographie
Vous trouverez ci-dessous les polices que vous utiliserez dans l'application.
Fichier du thème
Le fichier Theme.kt contient toutes les informations sur le thème de l'application, lequel est défini par des couleurs, des formes et une typographie. Il est important de garder ce fichier à l'esprit. Il se trouve le composable WoofTheme()
, qui définit les couleurs, la typographie et les formes de l'application.
@Composable
fun WoofTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
// Dynamic color is available on Android 12+
dynamicColor: Boolean = false,
content: @Composable () -> Unit
) {
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}
darkTheme -> DarkColors
else -> LightColors
}
val view = LocalView.current
if (!view.isInEditMode) {
SideEffect {
setUpEdgeToEdge(view, darkTheme)
}
}
MaterialTheme(
colorScheme = colorScheme,
shapes = Shapes,
typography = Typography,
content = content
)
}
/**
* Sets up edge-to-edge for the window of this [view]. The system icon colors are set to either
* light or dark depending on whether the [darkTheme] is enabled or not.
*/
private fun setUpEdgeToEdge(view: View, darkTheme: Boolean) {
val window = (view.context as Activity).window
WindowCompat.setDecorFitsSystemWindows(window, false)
window.statusBarColor = Color.Transparent.toArgb()
val navigationBarColor = when {
Build.VERSION.SDK_INT >= 29 -> Color.Transparent.toArgb()
Build.VERSION.SDK_INT >= 26 -> Color(0xFF, 0xFF, 0xFF, 0x63).toArgb()
// Min sdk version for this app is 24, this block is for SDK versions 24 and 25
else -> Color(0x00, 0x00, 0x00, 0x50).toArgb()
}
window.navigationBarColor = navigationBarColor
val controller = WindowCompat.getInsetsController(window, view)
controller.isAppearanceLightStatusBars = !darkTheme
controller.isAppearanceLightNavigationBars = !darkTheme
}
Dans MainActivity.kt, WoofTheme()
est ajouté pour fournir la thématisation Material à l'ensemble de l'application.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
WoofTheme {
Surface(
modifier = Modifier.fillMaxSize()
) {
WoofApp()
}
}
}
}
}
Examinez l'élément WoofPreview()
. WoofTheme()
a été ajouté pour ajouter la thématisation Material dans WoofPreview()
.
@Preview
@Composable
fun WoofPreview() {
WoofTheme(darkTheme = false) {
WoofApp()
}
}
3. Télécharger le code de démarrage
Pour commencer, téléchargez le code de démarrage :
Vous pouvez également cloner le dépôt GitHub du code :
$ git clone https://github.com/google-developer-training/basic-android-kotlin-compose-training-woof.git $ cd basic-android-kotlin-compose-training-woof $ git checkout starter
Vous pouvez parcourir le code dans le dépôt GitHub Woof app
.
Explorer le code de démarrage
- Ouvrez le code de démarrage dans Android Studio.
- Ouvrez com.example.woof > data > Dog.kt. Il contient le
Dog data class
qui sera utilisé pour représenter la photo, le nom, l'âge et les jeux préférés du chien. Il contient également une liste de chiens et les données que vous utiliserez dans votre application. - Ouvrez res > drawable. Il contient tous les éléments image dont vous avez besoin pour ce projet, y compris l'icône de l'application, les images de chiens et les icônes.
- Ouvrez res > values > strings.xml. Il contient les chaînes que vous utilisez dans cette application, y compris le nom de l'appli, les noms des chiens, leur description et plus encore.
- Ouvrez MainActivity.kt. Ce code permet de créer une liste simple qui affiche la photo d'un chien, son nom et son âge.
WoofApp()
contient un élémentLazyColumn
qui affiche les élémentsDogItem
.DogItem()
contient un élémentRow
qui affiche une photo du chien et des informations le concernant.DogIcon()
affiche une photo du chien.DogInformation()
affiche le nom et l'âge du chien.WoofPreview()
vous permet d'afficher un aperçu de l'application dans le volet Design (Conception).
Assurez-vous que votre émulateur/appareil est en thème clair.
Dans cet atelier de programmation, vous allez utiliser les thèmes clair et sombre. Toutefois, la majorité de l'atelier est en thème clair. Avant de commencer, assurez-vous que votre appareil ou votre émulateur est réglé sur le thème clair.
Pour afficher le thème clair dans votre application, sur votre émulateur ou sur votre appareil physique :
- Accédez à l'application Paramètres de l'appareil.
- Recherchez l'option Thème sombre pour y accéder.
- Si le thème sombre est activé, désactivez-le.
Exécutez le code de démarrage pour découvrir votre point de départ. Il s'agit d'une liste qui affiche les différents chiens, avec leur photo, leur nom et leur âge. L'application est fonctionnelle, mais elle n'est pas parfaite. Nous allons donc y remédier.
4. Ajouter une couleur
La première chose que vous allez modifier dans l'application Woof est le jeu de couleurs.
Il s'agit de la combinaison de couleurs utilisée par votre application. Les différentes combinaisons évoquent différentes émotions, ce qui a une influence sur la façon dont les utilisateurs se servent de votre application.
Dans le système Android, la couleur est représentée par une valeur hexadécimale (hex). Un code couleur hexadécimal commence par le caractère dièse (#), suivi de six lettres et/ou chiffres représentant les composants rouge, vert et bleu (RVB) de cette couleur. Les deux premières lettres/chiffres font référence au rouge, les deux caractères suivants au vert et les deux derniers au bleu.
Une couleur peut également inclure une valeur alpha (lettres et/ou chiffres) qui définit la transparence de la couleur (#00 correspond à une opacité de 0 %, entièrement transparent ; #FF à une opacité de 100 %, entièrement opaque). Lorsqu'elle est incluse, la valeur alpha correspond aux deux premiers caractères du code hexadécimal. Si aucune valeur alpha n'est incluse, il s'agit par défaut de #FF, qui représente une opacité de 100 % (entièrement opaque).
Vous trouverez ci-dessous des exemples de couleurs ainsi que leurs valeurs hexadécimales.
Utiliser Material Theme Builder pour créer un jeu de couleurs
Pour créer un jeu de couleurs personnalisé pour notre application, nous allons utiliser Material Theme Builder.
- Cliquez sur ce lien pour accéder à Material Theme Builder.
- Dans le volet de gauche, vous trouverez l'option "Core Colors" (Couleurs de base). Cliquez sur "Primary" (Couleur principale) :
- Le sélecteur de couleur HCT s'ouvre.
- Pour créer le jeu de couleurs présenté sur les captures d'écran de l'application, vous devrez changer la couleur principale dans ce sélecteur. Dans la zone de texte, remplacez la valeur actuelle par #006C4C. La couleur principale de l'application devient verte.
Vous pouvez alors remarquer que les applications à l'écran se mettent à jour pour adopter un jeu de couleurs centré sur le vert.
- Faites défiler la page. Le jeu de couleurs complet pour les thèmes clair et sombre est généré à partir de la couleur que vous avez choisie.
Vous vous demandez peut-être quels sont le rôle et le cas d'utilisation de chaque couleur. Voici de quoi éclairer votre lanterne :
- Les couleurs principales sont utilisées pour les principaux composants de l'interface utilisateur.
- Les couleurs secondaires sont utilisées pour les composants les moins visibles.
- Les couleurs tertiaires sont utilisées pour accentuer le contraste des couleurs principales et secondaires, ou pour attirer davantage l'attention sur un élément, comme un champ de saisie.
- Les éléments de couleur on apparaissent au-dessus des autres couleurs de la palette et sont principalement appliqués au texte, à l'iconographie et aux traits. Dans notre palette de couleurs, nous avons une couleur onSurface, qui apparaît au-dessus de la couleur de surface, et une couleur onPrimary, qui apparaît au-dessus de la couleur principale.
Ces encoches permettent d'harmoniser le système de conception, dans lequel les composants associés ont la même couleur.
Trêve de théorie des couleurs : il est temps d'ajouter cette magnifique palette à l'application !
Ajouter une palette de couleurs au thème
Sur la page de Material Theme Builder, vous pouvez cliquer sur le bouton Export (Exporter) pour télécharger un fichier Color.kt et un fichier Theme.kt avec le thème personnalisé que vous avez créé.
Ils permettront d'ajouter le thème personnalisé à votre application. Toutefois, comme le fichier Theme.kt généré n'inclut pas le code pour les couleurs dynamiques (dont nous parlerons plus tard dans cet atelier de programmation), vous devez copier les fichiers.
- Ouvrez le fichier Color.kt et remplacez son contenu par le code ci-dessous pour le copier dans le nouveau jeu de couleurs.
package com.example.woof.ui.theme
import androidx.compose.ui.graphics.Color
val md_theme_light_primary = Color(0xFF006C4C)
val md_theme_light_onPrimary = Color(0xFFFFFFFF)
val md_theme_light_primaryContainer = Color(0xFF89F8C7)
val md_theme_light_onPrimaryContainer = Color(0xFF002114)
val md_theme_light_secondary = Color(0xFF4D6357)
val md_theme_light_onSecondary = Color(0xFFFFFFFF)
val md_theme_light_secondaryContainer = Color(0xFFCFE9D9)
val md_theme_light_onSecondaryContainer = Color(0xFF092016)
val md_theme_light_tertiary = Color(0xFF3D6373)
val md_theme_light_onTertiary = Color(0xFFFFFFFF)
val md_theme_light_tertiaryContainer = Color(0xFFC1E8FB)
val md_theme_light_onTertiaryContainer = Color(0xFF001F29)
val md_theme_light_error = Color(0xFFBA1A1A)
val md_theme_light_errorContainer = Color(0xFFFFDAD6)
val md_theme_light_onError = Color(0xFFFFFFFF)
val md_theme_light_onErrorContainer = Color(0xFF410002)
val md_theme_light_background = Color(0xFFFBFDF9)
val md_theme_light_onBackground = Color(0xFF191C1A)
val md_theme_light_surface = Color(0xFFFBFDF9)
val md_theme_light_onSurface = Color(0xFF191C1A)
val md_theme_light_surfaceVariant = Color(0xFFDBE5DD)
val md_theme_light_onSurfaceVariant = Color(0xFF404943)
val md_theme_light_outline = Color(0xFF707973)
val md_theme_light_inverseOnSurface = Color(0xFFEFF1ED)
val md_theme_light_inverseSurface = Color(0xFF2E312F)
val md_theme_light_inversePrimary = Color(0xFF6CDBAC)
val md_theme_light_shadow = Color(0xFF000000)
val md_theme_light_surfaceTint = Color(0xFF006C4C)
val md_theme_light_outlineVariant = Color(0xFFBFC9C2)
val md_theme_light_scrim = Color(0xFF000000)
val md_theme_dark_primary = Color(0xFF6CDBAC)
val md_theme_dark_onPrimary = Color(0xFF003826)
val md_theme_dark_primaryContainer = Color(0xFF005138)
val md_theme_dark_onPrimaryContainer = Color(0xFF89F8C7)
val md_theme_dark_secondary = Color(0xFFB3CCBE)
val md_theme_dark_onSecondary = Color(0xFF1F352A)
val md_theme_dark_secondaryContainer = Color(0xFF354B40)
val md_theme_dark_onSecondaryContainer = Color(0xFFCFE9D9)
val md_theme_dark_tertiary = Color(0xFFA5CCDF)
val md_theme_dark_onTertiary = Color(0xFF073543)
val md_theme_dark_tertiaryContainer = Color(0xFF244C5B)
val md_theme_dark_onTertiaryContainer = Color(0xFFC1E8FB)
val md_theme_dark_error = Color(0xFFFFB4AB)
val md_theme_dark_errorContainer = Color(0xFF93000A)
val md_theme_dark_onError = Color(0xFF690005)
val md_theme_dark_onErrorContainer = Color(0xFFFFDAD6)
val md_theme_dark_background = Color(0xFF191C1A)
val md_theme_dark_onBackground = Color(0xFFE1E3DF)
val md_theme_dark_surface = Color(0xFF191C1A)
val md_theme_dark_onSurface = Color(0xFFE1E3DF)
val md_theme_dark_surfaceVariant = Color(0xFF404943)
val md_theme_dark_onSurfaceVariant = Color(0xFFBFC9C2)
val md_theme_dark_outline = Color(0xFF8A938C)
val md_theme_dark_inverseOnSurface = Color(0xFF191C1A)
val md_theme_dark_inverseSurface = Color(0xFFE1E3DF)
val md_theme_dark_inversePrimary = Color(0xFF006C4C)
val md_theme_dark_shadow = Color(0xFF000000)
val md_theme_dark_surfaceTint = Color(0xFF6CDBAC)
val md_theme_dark_outlineVariant = Color(0xFF404943)
val md_theme_dark_scrim = Color(0xFF000000)
- Ouvrez le fichier Theme.kt et remplacez le contenu par le code ci-dessous pour ajouter les nouvelles couleurs au thème.
package com.example.woof.ui.theme
import android.app.Activity
import android.os.Build
import android.view.View
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.core.view.WindowCompat
private val LightColors = lightColorScheme(
primary = md_theme_light_primary,
onPrimary = md_theme_light_onPrimary,
primaryContainer = md_theme_light_primaryContainer,
onPrimaryContainer = md_theme_light_onPrimaryContainer,
secondary = md_theme_light_secondary,
onSecondary = md_theme_light_onSecondary,
secondaryContainer = md_theme_light_secondaryContainer,
onSecondaryContainer = md_theme_light_onSecondaryContainer,
tertiary = md_theme_light_tertiary,
onTertiary = md_theme_light_onTertiary,
tertiaryContainer = md_theme_light_tertiaryContainer,
onTertiaryContainer = md_theme_light_onTertiaryContainer,
error = md_theme_light_error,
errorContainer = md_theme_light_errorContainer,
onError = md_theme_light_onError,
onErrorContainer = md_theme_light_onErrorContainer,
background = md_theme_light_background,
onBackground = md_theme_light_onBackground,
surface = md_theme_light_surface,
onSurface = md_theme_light_onSurface,
surfaceVariant = md_theme_light_surfaceVariant,
onSurfaceVariant = md_theme_light_onSurfaceVariant,
outline = md_theme_light_outline,
inverseOnSurface = md_theme_light_inverseOnSurface,
inverseSurface = md_theme_light_inverseSurface,
inversePrimary = md_theme_light_inversePrimary,
surfaceTint = md_theme_light_surfaceTint,
outlineVariant = md_theme_light_outlineVariant,
scrim = md_theme_light_scrim,
)
private val DarkColors = darkColorScheme(
primary = md_theme_dark_primary,
onPrimary = md_theme_dark_onPrimary,
primaryContainer = md_theme_dark_primaryContainer,
onPrimaryContainer = md_theme_dark_onPrimaryContainer,
secondary = md_theme_dark_secondary,
onSecondary = md_theme_dark_onSecondary,
secondaryContainer = md_theme_dark_secondaryContainer,
onSecondaryContainer = md_theme_dark_onSecondaryContainer,
tertiary = md_theme_dark_tertiary,
onTertiary = md_theme_dark_onTertiary,
tertiaryContainer = md_theme_dark_tertiaryContainer,
onTertiaryContainer = md_theme_dark_onTertiaryContainer,
error = md_theme_dark_error,
errorContainer = md_theme_dark_errorContainer,
onError = md_theme_dark_onError,
onErrorContainer = md_theme_dark_onErrorContainer,
background = md_theme_dark_background,
onBackground = md_theme_dark_onBackground,
surface = md_theme_dark_surface,
onSurface = md_theme_dark_onSurface,
surfaceVariant = md_theme_dark_surfaceVariant,
onSurfaceVariant = md_theme_dark_onSurfaceVariant,
outline = md_theme_dark_outline,
inverseOnSurface = md_theme_dark_inverseOnSurface,
inverseSurface = md_theme_dark_inverseSurface,
inversePrimary = md_theme_dark_inversePrimary,
surfaceTint = md_theme_dark_surfaceTint,
outlineVariant = md_theme_dark_outlineVariant,
scrim = md_theme_dark_scrim,
)
@Composable
fun WoofTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
// Dynamic color is available on Android 12+
dynamicColor: Boolean = false,
content: @Composable () -> Unit
) {
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}
darkTheme -> DarkColors
else -> LightColors
}
val view = LocalView.current
if (!view.isInEditMode) {
SideEffect {
setUpEdgeToEdge(view, darkTheme)
}
}
MaterialTheme(
colorScheme = colorScheme,
shapes = Shapes,
typography = Typography,
content = content
)
}
/**
* Sets up edge-to-edge for the window of this [view]. The system icon colors are set to either
* light or dark depending on whether the [darkTheme] is enabled or not.
*/
private fun setUpEdgeToEdge(view: View, darkTheme: Boolean) {
val window = (view.context as Activity).window
WindowCompat.setDecorFitsSystemWindows(window, false)
window.statusBarColor = Color.Transparent.toArgb()
val navigationBarColor = when {
Build.VERSION.SDK_INT >= 29 -> Color.Transparent.toArgb()
Build.VERSION.SDK_INT >= 26 -> Color(0xFF, 0xFF, 0xFF, 0x63).toArgb()
// Min sdk version for this app is 24, this block is for SDK versions 24 and 25
else -> Color(0x00, 0x00, 0x00, 0x50).toArgb()
}
window.navigationBarColor = navigationBarColor
val controller = WindowCompat.getInsetsController(window, view)
controller.isAppearanceLightStatusBars = !darkTheme
controller.isAppearanceLightNavigationBars = !darkTheme
}
Dans WoofTheme()
, colorScheme val
utilise une instruction when
.
- Si
dynamicColor
est "true" et que la version de compilation est S ou ultérieure, le système vérifie si l'appareil est endarkTheme
ou non. - Si c'est le cas et que le thème sombre est appliqué,
colorScheme
sera défini surdynamicDarkColorScheme
. - Dans le cas contraire, il sera défini sur
dynamicLightColorScheme
. - Si l'application n'utilise pas
dynamicColorScheme
, le système vérifie la présence dedarkTheme
. Si c'est bien le thème sombre qui est appliqué,colorScheme
sera défini surDarkColors
. - Si aucune de ces conditions n'est vraie,
colorScheme
est défini surLightColors
.
dynamicColor
est défini sur "false" dans le fichier Theme.kt copié et les appareils sur lesquels nous travaillons sont en mode clair. colorScheme
sera donc défini sur LightColors
.
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}
darkTheme -> DarkColors
else -> LightColors
}
- Exécutez à nouveau votre application. Notez que la barre d'application a automatiquement changé de couleur.
Mise en correspondance des couleurs
Les composants Material sont automatiquement mappés avec des encoches de couleur. D'autres composants clés de l'interface utilisateur, comme les boutons d'action flottants, sont définis par défaut sur la couleur primaire. Cela signifie que vous n'avez pas besoin d'attribuer explicitement une couleur à un composant. Le mappage sur une encoche de couleur est automatique lorsque vous définissez le thème dans votre application. Vous pouvez remplacer ce comportement en définissant explicitement une couleur dans le code. Cliquez ici pour savoir plus sur les rôles des couleurs.
Dans cette section, nous allons encapsuler le Row
contenant DogIcon()
et DogInformation()
avec un élément Card
pour différencier les couleurs des éléments de la liste avec l'arrière-plan.
- Dans la fonction composable
DogItem()
, encapsulezRow()
avec uneCard()
.
Card() {
Row(
modifier = modifier
.fillMaxWidth()
.padding(dimensionResource(id = R.dimen.padding_small))
) {
DogIcon(dog.imageResourceId)
DogInformation(dog.name, dog.age)
}
}
- Étant donné que le composable
Card
est désormais le premier élément enfant dansDogItem()
, transmettez le modificateurDogItem()
àCard
, puis mettez à jour le modificateur deRow
avec une nouvelle instance deModifier
.
Card(modifier = modifier) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(dimensionResource(id = R.dimen.padding_small))
) {
DogIcon(dog.imageResourceId)
DogInformation(dog.name, dog.age)
}
}
- Examinez l'élément
WoofPreview()
. Les éléments de la liste ont désormais changé automatiquement de couleur en raison des composablesCard
. Les couleurs sont attrayantes, mais il n'y a pas d'espace entre les éléments de la liste.
Fichier Dimens
Tout comme vous utilisez le fichier strings.xml pour stocker les chaînes dans votre application, il est également recommandé d'utiliser un fichier nommé dimens.xml pour stocker les valeurs des dimensions. Cette approche vous permet de ne pas coder en dur les valeurs et, si nécessaire, de les modifier à partir d'un emplacement centralisé.
Accédez à app > res > values > dimens.xml, puis examinez le fichier. Il stocke les valeurs des dimensions pour padding_small
, padding_medium
et image_size
. Ces dimensions seront utilisées dans toute l'application.
<resources>
<dimen name="padding_small">8dp</dimen>
<dimen name="padding_medium">16dp</dimen>
<dimen name="image_size">64dp</dimen>
</resources>
Pour ajouter une valeur au fichier dimens.xml, utilisez le format suivant :
Par exemple, pour ajouter padding_small
, vous devez transmettre dimensionResource(id = R.dimen.
padding_small
)
.
- Dans
WoofApp()
, ajoutez unmodifier
avecpadding_small
dans l'appel deDogItem()
.
@Composable
fun WoofApp() {
Scaffold { it ->
LazyColumn(contentPadding = it) {
items(dogs) {
DogItem(
dog = it,
modifier = Modifier.padding(dimensionResource(R.dimen.padding_small))
)
}
}
}
}
Dans WoofPreview()
, l'espacement entre les éléments de liste est désormais plus clair.
Thème sombre
Sur Android, vous pouvez activer le thème sombre sur votre appareil. Ce thème utilise des couleurs plus sombres et plus discrètes, et présente les avantages suivants :
- Il peut réduire considérablement la consommation d'énergie (selon la technologie d'écran de l'appareil).
- Il améliore la visibilité pour les utilisateurs souffrant d'une déficience visuelle et ceux sensibles à la lumière vive.
- Il permet à tous d'utiliser un appareil dans des conditions de faible luminosité.
Vous pouvez activer Forcer le mode sombre dans votre application pour que le système applique un thème sombre. Si vous forcez le thème sombre, vos utilisateurs bénéficient d'une meilleure expérience, ce qui vous permet de garder le contrôle du thème de l'application.
Lorsque vous choisissez votre propre thème sombre, notez que ses couleurs doivent respecter les normes d'accessibilité en matière de contraste. Ce type de thème utilise une couleur de surface sombre et limite les accentuations de couleur.
Afficher le thème sombre dans l'aperçu
Vous avez déjà ajouté les couleurs du thème sombre à l'étape précédente. Pour voir le thème sombre en action, vous devez ajouter un autre composable d'aperçu au fichier MainActivity.kt. Ainsi, lorsque vous modifiez la mise en page de l'interface utilisateur dans le code, vous pouvez voir simultanément à quoi ressemblent les thèmes clair et sombre.
- Sous
WoofPreview()
, créez une fonction appeléeWoofDarkThemePreview()
et annotez-la avec@Preview
et@Composable
.
@Preview
@Composable
fun WoofDarkThemePreview() {
}
- Dans
DarkThemePreview()
, ajoutezWoofTheme()
. SansWoofTheme()
, vous ne verrez aucun des styles que nous avons ajoutés dans l'application. Attribuez la valeur true au paramètredarkTheme
.
@Preview
@Composable
fun WoofDarkThemePreview() {
WoofTheme(darkTheme = true) {
}
}
- Appelez
WoofApp()
dansWoofTheme()
.
@Preview
@Composable
fun WoofDarkThemePreview() {
WoofTheme(darkTheme = true) {
WoofApp()
}
}
Faites maintenant défiler le volet Design (Conception) pour voir l'application avec le thème sombre. L'arrière-plan est plus sombre pour l'application dans son ensemble et pour les éléments de liste, et le texte plus clair. Comparez les différences entre les thèmes sombre et clair.
Thème sombre | Thème clair |
Afficher le thème sombre sur votre appareil ou votre émulateur
Pour afficher le thème sombre dans votre application, sur votre émulateur ou sur votre appareil physique :
- Accédez à l'application Paramètres de l'appareil.
- Recherchez l'option Thème sombre pour y accéder.
- Activez l'option Thème sombre.
- Rouvrez l'application Woof. Elle utilise le thème sombre.
Cet atelier de programmation porte davantage sur le thème clair. Avant de continuer, désactivez donc le thème sombre.
- Accédez à l'application Paramètres de l'appareil.
- Sélectionnez Affichage.
- Désactivez l'option Thème sombre.
Comparez l'apparence de l'application au début de la section et maintenant. Les éléments de liste et le texte sont plus définis, et le jeu de couleurs est plus esthétique.
Sans couleur | Avec couleur (thème clair) | Avec couleur (thème sombre) |
Couleurs dynamiques
Material 3 se concentre fortement sur la personnalisation. L'une des nouvelles fonctionnalités de cette version est la couleur dynamique, qui crée un thème pour votre application en fonction du fond d'écran de l'utilisateur. Ainsi, si l'utilisateur aime le vert et que l'arrière-plan de son téléphone est bleu, l'application Woof s'affichera en bleu. La thématisation dynamique n'est disponible que sur certains appareils équipés d'Android 12 ou version ultérieure.
Vous pouvez utiliser un thème personnalisé pour les applications qui utilisent des couleurs percutantes, par exemple pour renforcer une identité de marque. Il s'agit également d'une bonne solution pour les appareils qui ne sont pas compatibles avec la thématisation dynamique.
- Pour activer la couleur dynamique, ouvrez le fichier Theme.kt, puis accédez au composable
WoofTheme()
et définissez le paramètredynamicColor
sur true.
@Composable
fun WoofTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
dynamicColor: Boolean = true,
content: @Composable () -> Unit
)
- Pour modifier l'arrière-plan d'un appareil ou d'un émulateur, accédez aux Paramètres, puis recherchez Fond d'écran.
- Changez le fond d'écran pour utiliser une couleur ou un ensemble de couleurs.
- Réexécutez votre application pour afficher le thème dynamique (notez que votre appareil ou votre émulateur doit être équipé d'Android 12 ou version ultérieure). N'hésitez pas à tester cette fonctionnalité avec différents fonds d'écran.
- Cet atelier de programmation étant consacré aux thèmes personnalisés, désactivez
dynamicColor
avant de continuer.
@Composable
fun WoofTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
dynamicColor: Boolean = false,
content: @Composable () -> Unit
)
5. Ajouter une forme
L'application d'une forme peut modifier considérablement l'apparence d'un composable. Les formes permettent de capter l'attention, d'identifier les composants, de communiquer un état et d'exprimer une image de marque.
De nombreuses formes sont définies à l'aide de RoundedCornerShape
, qui décrit un rectangle avec des angles arrondis. Le nombre transmis définit l'arrondi des angles. Si vous utilisez RoundedCornerShape(0.dp)
, alors le rectangle n'a pas d'angles arrondis. Si vous utilisez RoundedCornerShape(50.dp)
, les angles sont entièrement arrondis.
0.dp | 25.dp | 50.dp |
Vous pouvez également personnaliser davantage les formes en ajoutant différents pourcentages d'arrondi à chaque angle. N'hésitez pas à faire quelques tests pour vous amuser !
En haut à gauche : 50.dp | En haut à gauche : 15.dp | En haut à gauche : 0.dp |
Le fichier Shape.kt est utilisé pour définir les formes des composants dans Compose. Il existe trois types de composants : petits, moyens et grands. Dans cette section, vous allez modifier le composant Card
, qui est défini sur la taille medium
. Les composants sont regroupés en catégories de formes en fonction de leur taille.
Dans cette section, vous appliquerez une forme arrondie à l'image du chien et modifierez la forme de l'élément de la liste.
Appliquer une forme arrondie à l'image de chien
- Ouvrez le fichier Shape.kt et notez que le paramètre "small" est défini sur
RoundedCornerShape(50.dp)
. C'est ce qui permet de donner une forme de cercle à l'image.
val Shapes = Shapes(
small = RoundedCornerShape(50.dp),
)
- Ouvrez MainActivity.kt. Dans
DogIcon()
, ajoutez un attributclip
aumodifier
deImage
. L'image sera découpée selon ces instructions. TransmettezMaterialTheme.shapes.small
.
import androidx.compose.ui.draw.clip
@Composable
fun DogIcon(
@DrawableRes dogIcon: Int,
modifier: Modifier = Modifier
) {
Image(
modifier = modifier
.size(dimensionResource(id = R.dimen.image_size))
.padding(dimensionResource(id = R.dimen.padding_small))
.clip(MaterialTheme.shapes.small),
Lorsque vous regardez WoofPreview()
, vous remarquerez que les icônes des chiens sont arrondies. Certaines photos sont cependant coupées sur les côtés, et la forme n'est pas pleinement arrondie.
- Pour arrondir les angles des photos, ajoutez un attribut
ContentScale
et un attributCrop
. L'image rentre maintenant dans le cadre arrondi. Notez quecontentScale
est un attribut deImage
, et ne fait pas partie demodifier
.
import androidx.compose.ui.layout.ContentScale
@Composable
fun DogIcon(
@DrawableRes dogIcon: Int,
modifier: Modifier = Modifier
) {
Image(
modifier = modifier
.size(dimensionResource(id = R.dimen.image_size))
.padding(dimensionResource(id = R.dimen.padding_small))
.clip(MaterialTheme.shapes.small),
contentScale = ContentScale.Crop,
Voici le composable DogIcon()
complet :
@Composable
fun DogIcon(
@DrawableRes dogIcon: Int,
modifier: Modifier = Modifier
) {
Image(
modifier = modifier
.size(dimensionResource(R.dimen.image_size))
.padding(dimensionResource(R.dimen.padding_small))
.clip(MaterialTheme.shapes.small),
contentScale = ContentScale.Crop,
painter = painterResource(dogIcon),
// Content Description is not needed here - image is decorative, and setting a null content
// description allows accessibility services to skip this element during navigation.
contentDescription = null
)
}
Dans WoofPreview()
, les icônes sont maintenant circulaires.
Appliquer une forme aux éléments de liste
Dans cette section, vous appliquerez une forme aux éléments de liste. Ils sont déjà affichés via un élément Card
. Une Card
est une surface qui peut contenir un seul composable et contient des options de décoration. Il est possible d'ajouter de la décoration en utilisant une bordure, une forme et bien plus. Dans cette section, vous utiliserez une Card
pour appliquer une forme à un élément de liste.
- Ouvrez le fichier Shape.kt.
Card
est un composant de type "medium". Vous devez donc ajouter le paramètre correspondant de l'objetShapes
. Pour cette application, nous allons arrondir les coins supérieur droit et inférieur gauche de chaque élément de liste, mais pas complètement. Pour ce faire, transmettez la valeur16.dp
à l'attributmedium
.
medium = RoundedCornerShape(bottomStart = 16.dp, topEnd = 16.dp)
Étant donné qu'un élément Card
utilise déjà par défaut la forme moyenne, vous n'avez pas besoin de la définir explicitement. Consultez l'aperçu pour voir la Card
avec sa nouvelle forme !
Si vous revenez au fichier Theme.kt dans WoofTheme()
et que vous examinez MaterialTheme()
, vous constaterez que l'attribut shapes
est défini sur la val
Shapes
que vous venez de mettre à jour.
MaterialTheme(
colors = colors,
typography = Typography,
shapes = Shapes,
content = content
)
Vous trouverez ci-dessous un aperçu des éléments de liste, avant et après la mise en forme. Comme vous pouvez le constater, les formes rendent l'application plus attrayante.
Sans mise en forme | Avec mise en forme |
6. Ajouter une typographie
L'échelle de type Material Design
Une échelle de type est une sélection de styles de police pouvant être utilisés dans une application pour garantir un style flexible mais cohérent. L'échelle de type Material Design comprend 15 styles de police compatibles avec ce système. La dénomination et le regroupement ont été simplifiés pour les affichages, les titres principaux, les titres, le corps de texte et les libellés, avec des tailles grandes, moyennes et petites pour chaque catégorie. N'utilisez ces choix que si vous souhaitez personnaliser votre application. Si vous ne savez pas quoi définir pour les catégories d'échelle de type, vous pouvez utiliser une échelle de typographie par défaut.
L'échelle de type contient des catégories de texte réutilisables, dont chacune a une utilisation et une signification spécifiques.
Affichage
S'agissant des éléments textuels les plus grands à l'écran, les styles d'affichage sont réservés au texte ou aux chiffres courts et importants. Ils sont mieux adaptés aux grands écrans.
Titre principal
Les titres principaux sont particulièrement adaptés aux textes courts à forte intensité sur les écrans plus petits. Ces styles permettent d'introduire des passages principaux du texte ou des zones de contenu importantes.
Titre
Les titres sont plus petits que les styles de titre principal et doivent être utilisés pour les textes d'accentuation relativement courts.
Corps
Les styles de corps sont utilisés pour les passages de texte plus longs dans votre application.
Libellé
Les styles de libellé sont plus petits et fonctionnels. Ils sont utilisés pour le texte à l'intérieur des composants ou pour le texte de taille réduite dans le corps du contenu, comme les sous-titres.
Polices
La plate-forme Android propose différentes polices, mais vous pouvez utiliser une police non fournie par défaut pour personnaliser votre application. Les polices personnalisées apportent une touche personnelle et peuvent être utilisées pour le branding.
Dans cette section, vous ajouterez les polices personnalisées Abril Fatface, Montserrat Bold et Montserrat Regular. Vous allez utiliser les titres displayLarge et displayMedium ainsi que le corps de texte bodyLarge, tous issus du système de types Material. Vous devrez les ajouter au texte de votre application.
Créer une police pour le répertoire de ressources Android
Avant d'ajouter des polices à votre application, vous devez ajouter un répertoire de polices.
- Dans la vue Projet d'Android Studio, faites un clic droit sur le dossier res.
- Sélectionnez New > Android Resource Directory (Nouveau > Répertoire des ressources Android).
- Nommez le répertoire font, définissez le type de ressource sur font, puis cliquez sur OK.
- Ouvrez votre nouveau répertoire de ressources de police sous res > font.
Télécharger des polices personnalisées
Puisque vous utilisez des polices qui ne sont pas fournies par la plate-forme Android, vous devez télécharger les polices personnalisées.
- Accédez à https://fonts.google.com/.
- Recherchez Montserrat, puis cliquez sur Download family (Télécharger la famille).
- Décompressez le fichier ZIP.
- Ouvrez le dossier Montserrat téléchargé. Dans le dossier static, recherchez Montserrat-Bold.ttf et Montserrat-Regular.ttf. L'acronyme TTF signifie "TrueType Font" (police TrueType) : il s'agit du format des fichiers de police. Sélectionnez les deux polices, puis faites-les glisser vers le répertoire de ressources de police de votre projet Android Studio.
- Dans votre dossier de polices, renommez Montserrat-Gold.ttf en montserrat_bold.ttf, et renommez Montserrat-Standard.ttf en montserrat_regular.ttf.
- Recherchez Abril Fatface et cliquez sur Download family (Télécharger la famille).
- Ouvrez le dossier Abril_Fatface téléchargé. Sélectionnez le fichier AbrilFatface-Regular.ttf et faites-le glisser dans le répertoire de ressources de police.
- Dans votre dossier de police, remplacez le nom du fichier Abril_Fatface_Regular.ttf par abril_fatface_regular.ttf.
Voici à quoi devrait ressembler le répertoire de ressources de polices dans votre projet, avec les trois fichiers de police personnalisée :
Initialiser les polices
- Dans la fenêtre du projet, ouvrez ui.theme > Type.kt. Initialisez les polices téléchargées sous les instructions d'importation et au-dessus de la
val
Typography
. Pour commencer, initialisez Abril Fatface en la définissant surFontFamily
, puis transmettezFont
avec le fichier de policeabril_fatface_regular
.
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import com.example.woof.R
val AbrilFatface = FontFamily(
Font(R.font.abril_fatface_regular)
)
- Initialisez Montserrat sous Abril Fatface en la définissant sur
FontFamily
et en transmettantFont
avec le fichier de policemontserrat_regular
. Pourmontserrat_bold
, incluez égalementFontWeight.Bold
. Même si vous transmettez la version "bold" (gras) du fichier de police, Compose ne sait pas que le fichier est en gras. Vous devez donc explicitement associer le fichier àFontWeight.Bold
.
import androidx.compose.ui.text.font.FontWeight
val AbrilFatface = FontFamily(
Font(R.font.abril_fatface_regular)
)
val Montserrat = FontFamily(
Font(R.font.montserrat_regular),
Font(R.font.montserrat_bold, FontWeight.Bold)
)
Ensuite, définissez les différents types de titres en fonction des polices que vous venez d'ajouter. L'objet Typography
comporte des paramètres pour 13 caractères différents, décrits ci-dessus. Vous pouvez en définir autant que nécessaire. Dans cette appli, nous allons définir displayLarge
, displayMedium
et bodyLarge
. Dans la partie suivante, vous utiliserez labelSmall
, donc nous allons également l'ajouter ici.
Vous trouverez ci-dessous un tableau indiquant la police, l'épaisseur et la taille de chaque titre ajouté.
- Définissez la valeur de l'attribut
displayLarge
sur la valeurTextStyle
, puis saisissez les informations du tableau ci-dessus dans les champsfontFamily
,fontWeight
etfontSize
. Autrement dit, tout le texte défini surdisplayLarge
utilisera la police Abril Fatface, avec une épaisseur de police normale et une propriétéfontSize
de36.sp
.
Répétez ces étapes pour displayMedium
, labelSmall
et bodyLarge
.
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.sp
val Typography = Typography(
displayLarge = TextStyle(
fontFamily = AbrilFatface,
fontWeight = FontWeight.Normal,
fontSize = 36.sp
),
displayMedium = TextStyle(
fontFamily = Montserrat,
fontWeight = FontWeight.Bold,
fontSize = 20.sp
),
labelSmall = TextStyle(
fontFamily = Montserrat,
fontWeight = FontWeight.Bold,
fontSize = 14.sp
),
bodyLarge = TextStyle(
fontFamily = Montserrat,
fontWeight = FontWeight.Normal,
fontSize = 14.sp
)
)
Si vous accédez au fichier Theme.kt dans WoofTheme()
et que vous examinez MaterialTheme()
, le paramètre typography
est égal à Typography val
, que vous venez de mettre à jour.
MaterialTheme(
colors = colors,
typography = Typography,
shapes = Shapes,
content = content
)
Appliquer une typographie au texte de l'application
Vous allez maintenant ajouter les types de titres à chaque instance de texte dans l'application.
- Ajoutez le style
displayMedium
pourdogName
, car il s'agit d'une information courte et importante. Ajoutez le stylebodyLarge
pourdogAge
: il est particulièrement adapté aux tailles de texte plus petites.
@Composable
fun DogInformation(
@StringRes dogName: Int,
dogAge: Int,
modifier: Modifier = Modifier
) {
Column(modifier = modifier) {
Text(
text = stringResource(dogName),
style = MaterialTheme.typography.displayMedium,
modifier = Modifier.padding(top = dimensionResource(id = R.dimen.padding_small))
)
Text(
text = stringResource(R.string.years_old, dogAge),
style = MaterialTheme.typography.bodyLarge
)
}
}
- À présent, dans
WoofPreview()
, le nom du chien s'affiche en police Montserrat, en gras et en taille20.sp
, tandis que son âge s'affiche en police Montserrat normale en taille14.sp
.
Vous trouverez ci-dessous un aperçu des éléments de liste, avant et après l'ajout de la typographie. Notez la différence de police entre le nom du chien et son âge.
Sans typographie | Avec typographie |
7. Ajouter une barre supérieure
Un Scaffold
, ou échafaudage, est une mise en page qui fournit des emplacements pour divers composants et éléments sur l'écran, tels que Image
, Row
ou Column
. Un Scaffold
fournit également un emplacement pour TopAppBar
, que vous utiliserez dans cette section.
La TopAppBar
peut être utilisée de plusieurs façons, mais dans ce cas, elle vous permettra de créer une image de marque et de donner une touche personnelle à votre application. Il existe quatre types de TopAppBar
différents : centré, petit, moyen et grand. Dans cet atelier de programmation, vous allez implémenter une barre d'application supérieure centrée. Vous allez créer un composable qui ressemble à la capture d'écran ci-dessous, et l'insérer dans la section topBar
d'un Scaffold
.
Pour cette application, la barre supérieure se compose d'un Row
avec un logo et du texte qui correspond au nom de l'application. Le logo inclut une petite patte en dégradé de couleur et le titre de l'application.
Ajouter une image et du texte à la barre supérieure
- Dans MainActivity.kt, créez un composable appelé
WoofTopAppBar()
. Si vous le souhaitez, vous pouvez lui ajouter unmodifier
.
@Composable
fun WoofTopAppBar(modifier: Modifier = Modifier) {
}
Scaffold
prend en charge le paramètrecontentWindowInsets
, qui permet de spécifier des encarts pour le contenu de l'échafaudage.WindowInsets
correspond aux parties de l'écran où votre application peut rentrer en conflit avec l'UI du système. Elles doivent être transmises à l'emplacement de contenu via les paramètresPaddingValues
. En savoir plus.
La valeur contentWindowInsets
est transmise à LazyColumn
en tant que contentPadding
.
@Composable
fun WoofApp() {
Scaffold { it ->
LazyColumn(contentPadding = it) {
items(dogs) {
DogItem(
dog = it,
modifier = Modifier.padding(dimensionResource(R.dimen.padding_small))
)
}
}
}
}
- Dans
Scaffold
, ajoutez un attributtopBar
et définissez-le surWoofTopAppBar()
.
Scaffold(
topBar = {
WoofTopAppBar()
}
)
Voici à quoi ressemble le composable WoofApp()
:
@Composable
fun WoofApp() {
Scaffold(
topBar = {
WoofTopAppBar()
}
) { it ->
LazyColumn(contentPadding = it) {
items(dogs) {
DogItem(
dog = it,
modifier = Modifier.padding(dimensionResource(R.dimen.padding_small))
)
}
}
}
}
Rien n'a changé dans WoofPreview()
, car WoofTopAppBar()
est vide. Remédions à ce problème.
- Dans
WoofTopAppBar() Composable
, ajoutezCenterAlignedTopAppBar()
et définissez le paramètre modificateur sur celui transmis dansWoofTopAppBar()
.
import androidx.compose.material3.CenterAlignedTopAppBar
@Composable
fun WoofTopAppBar(modifier: Modifier = Modifier) {
CenterAlignedTopAppBar(
modifier = modifier
)
}
- Pour le paramètre de titre, transmettez un
Row
qui contiendra les élémentsImage
etText
deCenterAlignedTopAppBar
.
@Composable
fun WoofTopAppBar(modifier: Modifier = Modifier){
CenterAlignedTopAppBar(
title = {
Row() {
}
},
modifier = modifier
)
}
- Ajoutez le logo
Image
dansRow
.
- Définissez la taille de l'image dans le
modifier
en tant queimage_size
dans le fichierdimens.xml
, puis fixez la marge intérieure avecpadding_small
dans le même fichierdimens.xml
. - Utilisez
painter
pour définirImage
suric_woof_logo
à partir du dossier drawable. - Définissez
contentDescription
sur null. Dans ce cas, le logo de l'application n'ajoute aucune information sémantique pour les utilisateurs malvoyants. Il n'est donc pas nécessaire d'ajouter une description du contenu.
Row() {
Image(
modifier = Modifier
.size(dimensionResource(id = R.dimen.image_size))
.padding(dimensionResource(id = R.dimen.padding_small)),
painter = painterResource(R.drawable.ic_woof_logo),
contentDescription = null
)
}
- Ajoutez ensuite un composable
Text
dansRow
après l'élémentImage.
.
- Utilisez
stringResource()
pour le définir sur la valeur deapp_name
. Le texte prendra alors le nom de l'application, stocké dansstrings.xml
. - Définissez le style du texte sur
displayLarge
, car le nom de l'application est une information courte et importante.
Text(
text = stringResource(R.string.app_name),
style = MaterialTheme.typography.displayLarge
)
Voici ce qui s'affiche dans WoofPreview()
. L'apparence n'est pas parfaite, car l'icône et le texte ne sont pas alignés verticalement.
- Pour résoudre ce problème, ajoutez un paramètre de valeur
verticalAlignment
àRow
et définissez-le surAlignment.CenterVertically
.
import androidx.compose.ui.Alignment
Row(
verticalAlignment = Alignment.CenterVertically
)
C'est beaucoup mieux !
Voici le composable WoofTopAppBar()
complet :
@Composable
fun WoofTopAppBar(modifier: Modifier = Modifier) {
CenterAlignedTopAppBar(
title = {
Row(
verticalAlignment = Alignment.CenterVertically
) {
Image(
modifier = Modifier
.size(dimensionResource(id = R.dimen.image_size))
.padding(dimensionResource(id = R.dimen.padding_small)),
painter = painterResource(R.drawable.ic_woof_logo),
contentDescription = null
)
Text(
text = stringResource(R.string.app_name),
style = MaterialTheme.typography.displayLarge
)
}
},
modifier = modifier
)
}
Exécutez l'application et admirez la façon dont la TopAppBar
se fond élégamment avec le reste.
Sans barre d'application supérieure | Avec la barre d'application supérieure |
Et maintenant, observez la version finale de l'application avec le thème sombre !
Félicitations, vous avez terminé cet atelier de programmation !
8. Télécharger le code de solution
Pour télécharger le code de cet atelier de programmation terminé, utilisez les commandes Git suivantes :
$ git clone https://github.com/google-developer-training/basic-android-kotlin-compose-training-woof.git $ cd basic-android-kotlin-compose-training-woof $ git checkout material
Vous pouvez également télécharger le dépôt sous forme de fichier ZIP, le décompresser et l'ouvrir dans Android Studio.
Si vous souhaitez voir le code de solution, affichez-le sur GitHub.
9. Conclusion
Vous venez de créer votre première application Material. Vous avez créé une palette de couleurs personnalisée pour le thème clair et le thème sombre, créé des formes pour différents composants, téléchargé des polices et ajouté ces éléments à l'application, puis créé une belle barre supérieure pour unifier le tout. Mettez à profit les compétences acquises dans cet atelier de programmation pour modifier les couleurs, les formes et la typographie afin d'apporter une touche personnelle à vos applications !
Résumé
- La thématisation Material vous permet d'utiliser Material Design dans votre application et vous offre des conseils pour personnaliser ses couleurs, sa typographie et ses formes.
- Le thème est défini dans le fichier Theme.kt via un composable appelé
[your app name]+Theme()
(WoofTheme()
), dans le cas de cette appli. Dans cette fonction, l'objetMaterialTheme
définit les paramètrescolor
,typography
,shapes
etcontent
. - Color.kt vous permet de définir la liste des couleurs que vous utilisez dans l'application. Ensuite, dans Theme.kt, vous attribuez les couleurs dans
LightColorPalette
etDarkColorPalette
à des emplacements spécifiques. Il n'est pas nécessaire d'attribuer tous les emplacements. - Vous pouvez activer Forcer le mode sombre dans votre application pour que le système applique un thème sombre. Si vous forcez le thème sombre, vos utilisateurs bénéficient d'une meilleure expérience, ce qui vous permet de garder le contrôle du thème de l'application.
- Shape.kt vous permet de définir les formes de votre application. Il existe trois tailles possibles : petite, moyenne et grande. Vous pouvez régler l'arrondi des angles.
- Les formes permettent de capter l'attention, d'identifier les composants, de communiquer un état et d'exprimer une image de marque.
- Dans le fichier Type.kt, vous initialisez vos polices et attribuez les propriétés
fontFamily
,fontWeight
etfontSize
pour l'échelle de type Material Design. - L'échelle de type Material Design comprend une gamme de styles contrastés qui répondent aux besoins de votre application et de son contenu. L'échelle de type combine 15 styles compatibles avec le système de types.