Les API Material, Compose UI et Foundation implémentent et proposent de nombreuses pratiques accessibles par défaut. Ils contiennent une sémantique intégrée qui suit leur rôle et leur fonction spécifiques, ce qui signifie que la plupart des fonctionnalités d'accessibilité sont fournies avec peu ou pas de travail supplémentaire.
L'utilisation des API appropriées à des fins appropriées signifie généralement que les composants sont fournis avec des comportements d'accessibilité prédéfinis qui couvrent les cas d'utilisation standards. N'oubliez pas de vérifier que ces valeurs par défaut répondent à vos besoins d'accessibilité. Sinon, Compose offre également des moyens de répondre à des exigences plus spécifiques.
Connaître les sémantiques et les modèles d'accessibilité par défaut des API Compose permet de comprendre comment les utiliser en tenant compte de l'accessibilité, ainsi que de prendre en charge l'accessibilité dans des composants plus personnalisés.
Tailles minimales des cibles tactiles
Tout élément à l'écran sur lequel un utilisateur peut cliquer ou appuyer, ou avec lequel il peut interagir, doit être assez grand pour permettre une interaction fiable. Lorsque vous dimensionnez ces éléments, assurez-vous de définir la taille minimale sur 48 dp de manière à respecter les consignes d'accessibilité de Material Design.
Pour les composants Material, comme Checkbox
, RadioButton
, Switch
, Slider
et Surface
, définissez cette taille minimale en interne, mais seulement lorsque l'utilisateur peut agir dessus. Par exemple, lorsque le paramètre onCheckedChange
d'une Checkbox
a une valeur non nulle, la case à cocher inclut une marge intérieure dont la largeur et la hauteur sont d'au moins 48 dp.
@Composable private fun CheckableCheckbox() { Checkbox(checked = true, onCheckedChange = {}) }

Lorsque le paramètre onCheckedChange
est défini sur nul, la marge intérieure n'est pas incluse, car il est impossible d'interagir directement avec le composant.
@Composable private fun NonClickableCheckbox() { Checkbox(checked = true, onCheckedChange = null) }

Lorsque vous implémentez des commandes de sélection telles que Switch
, RadioButton
ou Checkbox
, vous élevez généralement le comportement cliquable au rang d'un conteneur parent en définissant le rappel de clic sur le composable sur null
, puis en ajoutant un modificateur toggleable
ou selectable
au composable parent.
@Composable private fun CheckableRow() { MaterialTheme { var checked by remember { mutableStateOf(false) } Row( Modifier .toggleable( value = checked, role = Role.Checkbox, onValueChange = { checked = !checked } ) .padding(16.dp) .fillMaxWidth() ) { Text("Option", Modifier.weight(1f)) Checkbox(checked = checked, onCheckedChange = null) } } }

Lorsque la taille d'un composable cliquable est inférieure à la taille minimale de la cible tactile, Compose augmente quand même les dimensions de cette zone. Pour ce faire, il étend la taille de la cible tactile au-delà des limites du composable.
L'exemple suivant contient une toute petite Box
cliquable. La superficie de la cible tactile est automatiquement étendue au-delà des limites de cette Box
. Par conséquent le fait d'appuyer à côté de Box
déclenche quand même l'événement de clic.
@Composable private fun SmallBox() { var clicked by remember { mutableStateOf(false) } Box( Modifier .size(100.dp) .background(if (clicked) Color.DarkGray else Color.LightGray) ) { Box( Modifier .align(Alignment.Center) .clickable { clicked = !clicked } .background(Color.Black) .size(1.dp) ) } }

Pour éviter tout chevauchement potentiel entre les zones tactiles des différents composables, utilisez toujours une taille minimale assez grande pour le composable. Dans l'exemple, cela implique d'utiliser le modificateur sizeIn
pour définir la taille minimale du champ intérieur:
@Composable private fun LargeBox() { var clicked by remember { mutableStateOf(false) } Box( Modifier .size(100.dp) .background(if (clicked) Color.DarkGray else Color.LightGray) ) { Box( Modifier .align(Alignment.Center) .clickable { clicked = !clicked } .background(Color.Black) .sizeIn(minWidth = 48.dp, minHeight = 48.dp) ) } }

Éléments graphiques
Lorsque vous définissez un composable Image
ou Icon
, il n'existe pas de moyen automatique pour que le framework Android comprenne ce que l'application affiche. Vous devez transmettre une description textuelle de l'élément graphique.
Imaginez un écran sur lequel l'utilisateur peut partager la page active avec ses amis. Cet écran contient une icône de partage cliquable :

S'il ne dispose que de cette seule icône, le framework Android ne peut pas la décrire à un utilisateur malvoyant. Le framework Android a besoin d'une description textuelle supplémentaire de l'icône.
Le paramètre contentDescription
décrit un élément graphique. Utilisez une chaîne localisée, car elle est visible par l'utilisateur.
@Composable private fun ShareButton(onClick: () -> Unit) { IconButton(onClick = onClick) { Icon( imageVector = Icons.Filled.Share, contentDescription = stringResource(R.string.label_share) ) } }
Certains éléments graphiques sont purement décoratifs, et vous ne souhaitez peut-être pas les communiquer à l'utilisateur. Lorsque vous définissez le paramètre contentDescription
sur null
, vous indiquez au framework Android que cet élément n'est associé à aucune action ni aucun état.
@Composable private fun PostImage(post: Post, modifier: Modifier = Modifier) { val image = post.imageThumb ?: painterResource(R.drawable.placeholder_1_1) Image( painter = image, // Specify that this image has no semantic meaning contentDescription = null, modifier = modifier .size(40.dp, 40.dp) .clip(MaterialTheme.shapes.small) ) }
contentDescription
est principalement destiné aux éléments graphiques, tels que les images. Les composants Material, tels que Button
ou Text
, et les comportements exploitables, tels que clickable
ou toggleable
, sont fournis avec d'autres sémantiques prédéfinies qui décrivent leur comportement intrinsèque et peuvent être modifiées via d'autres API Compose.
Éléments interactifs
Les API Material et Foundation Compose créent des éléments d'interface utilisateur avec lesquels les utilisateurs peuvent interagir via les API de modification clickable
et toggleable
. Étant donné que les composants interactifs peuvent se composer de plusieurs éléments, clickable
et toggleable
fusionnent les sémantiques de leurs enfants par défaut, de sorte que le composant soit traité comme une entité logique.
Par exemple, un Button
Material peut consister en une icône enfant et du texte.
Au lieu de traiter les enfants comme des individus, un bouton Material fusionne les sémantiques de ses enfants par défaut, afin que les services d'accessibilité puissent les regrouper en conséquence:

De même, l'utilisation du modificateur clickable
entraîne également la fusion de la sémantique de ses descendants dans une seule entité, qui est envoyée aux services d'accessibilité avec une représentation d'action correspondante:
Row( // Uses `mergeDescendants = true` under the hood modifier = Modifier.clickable { openArticle() } ) { Icon( painter = painterResource(R.drawable.ic_logo), contentDescription = "Open", ) Text("Accessibility in Compose") }
Vous pouvez également définir un onClickLabel
spécifique sur le composant parent cliquable pour fournir des informations supplémentaires aux services d'accessibilité et offrir une représentation plus soignée de l'action:
Row( modifier = Modifier .clickable(onClickLabel = "Open this article") { openArticle() } ) { Icon( painter = painterResource(R.drawable.ic_logo), contentDescription = "Open" ) Text("Accessibility in Compose") }
Prenons l'exemple de TalkBack. Ce modificateur clickable
et son libellé de clic permettraient à TalkBack de fournir un indice d'action "Appuyez deux fois pour ouvrir cet article", plutôt que le retour par défaut plus générique "Appuyez deux fois pour activer".
Ces commentaires varient en fonction du type d'action. Un clic prolongé fournit une astuce TalkBack "Appuyez deux fois et maintenez pour", suivie d'un libellé:
Row( modifier = Modifier .combinedClickable( onLongClickLabel = "Bookmark this article", onLongClick = { addToBookmarks() }, onClickLabel = "Open this article", onClick = { openArticle() }, ) ) {}
Dans certains cas, vous n'avez pas accès direct au modificateur clickable
(par exemple, lorsqu'il est défini dans une couche imbriquée inférieure),mais vous souhaitez tout de même modifier le libellé de l'annonce par défaut. Pour ce faire, séparez la définition de clickable
de la modification de l'annonce à l'aide du modificateur semantics
et définissez le libellé de clic à cet endroit pour modifier la représentation de l'action:
@Composable private fun ArticleList(openArticle: () -> Unit) { NestedArticleListItem( // Clickable is set separately, in a nested layer: onClickAction = openArticle, // Semantics are set here: modifier = Modifier.semantics { onClick( label = "Open this article", action = { // Not needed here: openArticle() true } ) } ) }
Dans ce cas, vous n'avez pas besoin de transmettre l'action de clic deux fois, car les API Compose existantes, comme clickable
ou Button
, s'en chargent. En effet, la logique de fusion garantit que le libellé et l'action de modification les plus externes sont appliqués aux informations présentes.
Dans l'exemple précédent, l'action de clic openArticle()
est transmise automatiquement par le NestedArticleListItem
à ses sémantiques clickable
et peut être laissée nulle dans la deuxième action de modification des sémantiques. Toutefois, le libellé de clic est extrait du deuxième modificateur de sémantique onClick(label = "Open this article")
, car il n'était pas présent dans le premier.
Vous pouvez rencontrer des scénarios où vous vous attendez à ce que les sémantiques enfants soient fusionnées dans une sémantique parente, mais cela ne se produit pas. Pour en savoir plus, consultez la section Fusionner et effacer.
Composants personnalisés
Pour les composants personnalisés, en règle générale, examinez l'implémentation d'un composant similaire dans la bibliothèque Material ou d'autres bibliothèques Compose, et imitez ou modifiez son comportement d'accessibilité lorsque cela est approprié.
Par exemple, si vous remplacez la Checkbox
Material par votre propre implémentation, l'examen de l'implémentation de la case à cocher existante vous rappellera d'ajouter le modificateur triStateToggleable
, qui gère les propriétés d'accessibilité de ce composant.
Utilisez également de manière intensive les modificateurs de base, car ils incluent des éléments d'accessibilité prêts à l'emploi, ainsi que les pratiques Compose existantes abordées dans cette section.
Vous trouverez également un exemple de composant de bouton d'activation/de désactivation personnalisé dans la section Section "Effacer et définir la sémantique", ainsi que des informations plus détaillées sur l'accessibilité dans les composants personnalisés dans les Consignes relatives à l'API.
Recommandations personnalisées
- Remarque : Le texte du lien s'affiche lorsque JavaScript est désactivé
- Accessibilité dans Compose
- [Material Design 2 dans Compose][19]
- Tester votre mise en page Compose