Pour aider les personnes ayant des besoins d'accessibilité à utiliser votre application avec succès, concevez votre pour répondre aux principales exigences d'accessibilité.
Définissez une taille minimale pour les zones 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éfinissez une taille minimale de 48 dp pour respecter les consignes consignes d'accessibilité.
Les composants Material, tels que Checkbox
, RadioButton
, Switch
,
Slider
et Surface
: définissez cette taille minimale en interne, mais seulement
lorsque le composant peut recevoir des actions de l'utilisateur. Par exemple, lorsqu'un Checkbox
a
son paramètre onCheckedChange
défini sur une valeur non nulle, la case à cocher inclut
avec une largeur et une hauteur d'au moins 48 dp.
@Composable private fun CheckableCheckbox() { Checkbox(checked = true, onCheckedChange = {}) }
Lorsque le paramètre onCheckedChange
est défini sur "null", la marge intérieure n'est pas
car il n'est pas possible d'interagir directement avec le composant.
@Composable private fun NonClickableCheckbox() { Checkbox(checked = true, onCheckedChange = null) }
Lorsque vous implémentez des contrôles de sélection tels que Switch
, RadioButton
ou
Checkbox
, vous transférez généralement le comportement cliquable vers un conteneur parent, défini
le rappel de clic sur le composable à null
, et ajoutez un 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 zone cible tactile, Compose augmente quand même les dimensions de cette zone. Pour ce faire, elle développe la taille de la zone cible tactile en dehors des limites du composable.
L'exemple suivant contient un élément Box
cliquable de très petite taille. La cible tactile
est automatiquement étendue au-delà des limites du Box
.
à côté de Box
déclenche toujours 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 éventuel entre les zones tactiles de différents composables,
utilisez une taille minimale suffisamment grande pour le composable. Dans l'exemple, il s'agirait
Moyenne de l'utilisation du modificateur sizeIn
pour définir la taille minimale de la zone intérieure:
@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) ) } }
Ajouter des étiquettes de clic
Vous pouvez utiliser une étiquette de clic pour ajouter une signification sémantique au comportement de clic d'un composable. Les libellés de clic décrivent ce qui se passe lorsque l'utilisateur interagit avec composable. Les services d'accessibilité utilisent des libellés de clic pour décrire l'application les utilisateurs ayant des besoins spécifiques.
Définissez le libellé de clic en transmettant un paramètre dans le modificateur clickable
:
@Composable private fun ArticleListItem(openArticle: () -> Unit) { Row( Modifier.clickable( // R.string.action_read_article = "read article" onClickLabel = stringResource(R.string.action_read_article), onClick = openArticle ) ) { // .. } }
Si vous n'avez pas accès au modificateur cliquable, L'étiquette de clic dans le modificateur sémantique:
@Composable private fun LowLevelClickLabel(openArticle: () -> Boolean) { // R.string.action_read_article = "read article" val readArticleLabel = stringResource(R.string.action_read_article) Canvas( Modifier.semantics { onClick(label = readArticleLabel, action = openArticle) } ) { // .. } }
Décrire les éléments visuels
Lorsque vous définissez un composable Image
ou Icon
,
moyen automatique pour le framework Android de comprendre l'application.
s'affiche. Vous devez transmettre une description textuelle de l'élément visuel.
Imaginez un écran sur lequel l'utilisateur peut partager la page active avec ses amis. Cet écran contient une icône de partage cliquable :
En se basant uniquement sur l'icône, le framework Android ne peut pas la décrire utilisateur altéré. Le framework Android a besoin d'une description textuelle supplémentaire l'icône.
Le paramètre contentDescription
décrit un élément visuel. Utilisez une version localisée
telle qu'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 visuels sont purement décoratifs et vous ne voulez peut-être pas communiquer
à l'utilisateur. Lorsque vous définissez le paramètre contentDescription
sur null
, vous
indique au framework Android que cet élément n'est associé à aucune
les actions ou l'é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) ) }
C'est à vous de décider si un élément visuel spécifique a besoin d'une contentDescription
. Demandez-vous si l’élément transmet des informations qui
l'utilisateur devra
effectuer sa tâche. Si ce n'est pas le cas, mieux vaut quitter
la description.
Fusionner des éléments
Les services d'accessibilité tels que TalkBack et Switch Access permettent aux utilisateurs de déplacer le curseur sur les différents éléments à l'écran. Il est important que les éléments soient sélectionnés avec la précision appropriée. Lorsque chaque composable de bas niveau sur votre écran est concentrés de manière indépendante, les utilisateurs doivent interagir beaucoup pour se déplacer sur l'écran. Si les éléments fusionnent de manière trop agressive, les utilisateurs pourraient ne pas comprendre lesquels les éléments s'unissent
Lorsque vous appliquez un modificateur clickable
à un composable, Compose
fusionne automatiquement tous les éléments que contient le composable. Cela vaut également pour
ListItem
; les éléments d'un même élément de liste fusionnent et l'accessibilité
services les voient
comme un seul élément.
Il se peut qu'un ensemble de composables constitue un groupe logique, mais que ce groupe ne soit pas cliquable ou ne fasse pas partie d'un élément de liste. L'accessibilité doit toujours être au rendez-vous pour les afficher comme un seul élément. Par exemple, imaginez un composable qui affiche l'avatar de l'utilisateur, son nom et d'autres informations:
Vous pouvez autoriser Compose à fusionner ces éléments à l'aide de l'mergeDescendants
dans le modificateur semantics
. De cette façon, les services d'accessibilité
sélectionner uniquement l'élément fusionné et toutes les propriétés sémantiques des descendants
sont fusionnées.
@Composable private fun PostMetadata(metadata: Metadata) { // Merge elements below for accessibility purposes Row(modifier = Modifier.semantics(mergeDescendants = true) {}) { Image( imageVector = Icons.Filled.AccountCircle, contentDescription = null // decorative ) Column { Text(metadata.author.name) Text("${metadata.date} • ${metadata.readTimeMinutes} min read") } } }
Les services d'accessibilité se concentrent désormais sur l'ensemble du conteneur leur contenu:
Ajouter des actions personnalisées
Examinez l'élément de liste suivant :
Lorsque vous utilisez un lecteur d'écran tel que TalkBack pour entendre ce qui est affiché sur le il sélectionne d'abord l'intégralité de l'élément, puis l'icône des favoris.
Dans une longue liste, cela peut devenir très répétitif. Une meilleure approche consiste à
Définir une action personnalisée qui permet à un utilisateur d'ajouter l'élément à ses favoris À retenir
vous devez également supprimer explicitement le comportement de l'icône de favori
pour s'assurer qu'il n'est pas sélectionné
par le service d'accessibilité. Ce
se fait avec le modificateur clearAndSetSemantics
:
@Composable private fun PostCardSimple( /* ... */ isFavorite: Boolean, onToggleFavorite: () -> Boolean ) { val actionLabel = stringResource( if (isFavorite) R.string.unfavorite else R.string.favorite ) Row( modifier = Modifier .clickable(onClick = { /* ... */ }) .semantics { // Set any explicit semantic properties customActions = listOf( CustomAccessibilityAction(actionLabel, onToggleFavorite) ) } ) { /* ... */ BookmarkButton( isBookmarked = isFavorite, onClick = onToggleFavorite, // Clear any semantics properties set on this node modifier = Modifier.clearAndSetSemantics { } ) } }
Décrire l'état d'un élément
Un composable peut définir une stateDescription
pour la sémantique,
Le framework Android utilise pour lire l'état dans lequel se trouve le composable. Pour
Par exemple, un composable à activer/désactiver peut se trouver dans un emplacement "coché" ou une case
« décochée »
de l'état. Dans certains cas, vous pouvez remplacer la description de l'état par défaut
étiquettes utilisées par Compose. Pour ce faire, spécifiez explicitement l'état
des étiquettes de description avant de définir un composable comme activable:
@Composable private fun TopicItem(itemTitle: String, selected: Boolean, onToggle: () -> Unit) { val stateSubscribed = stringResource(R.string.subscribed) val stateNotSubscribed = stringResource(R.string.not_subscribed) Row( modifier = Modifier .semantics { // Set any explicit semantic properties stateDescription = if (selected) stateSubscribed else stateNotSubscribed } .toggleable( value = selected, onValueChange = { onToggle() } ) ) { /* ... */ } }
Définir des titres
Les applications affichent parfois de nombreux contenus sur un seul écran dans un conteneur à faire défiler. Par exemple, un écran peut afficher le contenu complet d'un article que l'utilisateur lit :
Les utilisateurs ayant des besoins en termes d'accessibilité ont des difficultés à naviguer sur un tel écran. Pour vous aider la navigation, indiquer quels éléments sont des en-têtes. Dans l'exemple précédent, chaque le titre de la sous-section peut être défini comme un titre pour l'accessibilité. Un peu les services d'accessibilité, comme TalkBack, permettent aux utilisateurs de naviguer directement vers un titre.
Dans Compose, vous indiquez qu'un composable est un titre en définissant son
Propriété semantics
:
@Composable private fun Subsection(text: String) { Text( text = text, style = MaterialTheme.typography.headlineSmall, modifier = Modifier.semantics { heading() } ) }
Gérer les composables personnalisés
Chaque fois que vous remplacez certains composants Material de votre application par des versions, vous devez garder à l'esprit les considérations d'accessibilité.
Supposons que vous remplaciez Material Checkbox
par votre propre implémentation.
Vous pouvez oublier d'ajouter le modificateur triStateToggleable
, qui gère
les propriétés d'accessibilité de ce composant.
En règle générale, examinez l'implémentation du composant dans la bibliothèque Material et imiter n'importe quel comportement d'accessibilité que vous pouvez trouver. Utilisez également de manière intensive les modificateurs de base plutôt que les modificateurs de niveau de l'interface utilisateur, car ils incluent des éléments d'accessibilité prêts à l'emploi.
Testez l'implémentation de vos composants personnalisés avec plusieurs des services d'accessibilité pour vérifier son comportement.
Ressources supplémentaires
- Accessibilité:concepts et concepts essentiels techniques communes au développement d'applications Android
- Créer des applications accessibles:étapes clés pour rendre votre application plus accessible
- Principes d'amélioration d'une application accessibilité:principes clés pour à garder à l'esprit lorsque vous cherchez à rendre votre application plus accessible
- Tests d'accessibilité: Tester les principes et les outils d'accessibilité sur Android