Kotlin accessible : écrire du code qui n'abandonne pas les utilisateurs

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Pourquoi l'accessibilité en Kotlin est un super-pouvoir, pas une simple case à cocher

\n\n

Imaginez : vous avez écrit une super application en Kotlin. Un beau Material Design, des animations fluides, des flux réactifs. Vous êtes fier de votre code. Mais ensuite, il s'avère qu'une personne malvoyante ne peut pas appuyer sur le bouton « Acheter », car TalkBack le lit comme « bouton non étiqueté ». Ou qu'un utilisateur avec un tremblement des mains rate le minuscule interrupteur.

\n\n

L'accessibilité n'est pas une bureaucratie ennuyeuse. C'est faire en sorte que votre code Kotlin fonctionne pour tout le monde. Selon l'OMS, plus d'un milliard de personnes ont un handicap. Les ignorer, c'est perdre une audience et, honnêtement, être un mauvais développeur.

\n\n

Dans cet article, nous verrons comment écrire du code accessible en Kotlin sans douleur. Sans tonnes de code passe-partout. Avec des exemples concrets que vous pouvez copier-coller dès maintenant.

\n\n

Principes de base : ContentDescription, votre meilleur ami

\n\n

L'échec le plus fréquent en accessibilité est l'absence de description pour les éléments de l'interface. Le système TalkBack (lecteur d'écran sur Android) ne sait pas lire les images ou les icônes. Il a besoin de texte.

\n\n

En Kotlin, cela se fait via l'attribut contentDescription. Mais pas simplement « Bouton », plutôt de manière significative.

\n\n

Mauvais exemple (à ne pas faire)

\n
imageView.contentDescription = "Bouton"
\n\n

Bon exemple

\n
binding.fabAddTask.contentDescription = "Ajouter une nouvelle tâche"
\n\n

Si l'icône est décorative (simple ornement) — définissez contentDescription = null pour que TalkBack l'ignore.

\n\n
// Icône décorative — ne pas distraire l'utilisateur\nbinding.decorativeIcon.contentDescription = null
\n\n

Conseil : Utilisez les ressources de chaînes (strings.xml) pour prendre en charge la localisation. Ne codez pas en dur le texte français dans les fichiers Kotlin.

\n\n

Balisage sémantique : dire au système ce qui est important

\n\n

Les View standards (Button, TextView) s'en sortent bien, mais les composants personnalisés cassent souvent l'accessibilité. En Kotlin, nous pouvons définir explicitement la sémantique.

\n\n

Ajouter un rôle à l'élément

\n
binding.customView.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_YES\nbinding.customView.accessibilityDelegate = object : View.AccessibilityDelegate() {\n    override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfo) {\n        super.onInitializeAccessibilityNodeInfo(host, info)\n        info.text = "Valeur actuelle : ${viewModel.value}"\n        info.contentDescription = "Curseur de volume"\n    }\n}
\n\n

Ce code dit au système : « Hé, ce n'est pas juste un carré, c'est un curseur ! ». TalkBack comprendra que l'élément est interactif et pourra interagir correctement.

\n\n

Regroupement d'éléments

\n

Si vous avez une fiche produit avec une image, un prix et un nom — regroupez-les en un seul focus. Sinon, l'utilisateur écoutera trois éléments séparément.

\n\n
binding.cardProduct.apply {\n    isFocusable = true\n    contentDescription = "Produit : ${product.name}, prix : ${product.price} euros"\n}
\n\n

Maintenant, TalkBack lira toutes les informations en un seul clic.

\n\n

Navigation par action : clavier et D-pad

\n\n

Tous les utilisateurs ne tapent pas sur l'écran avec le doigt. Certains utilisent un clavier (via OTG) ou un D-pad (télécommande). Votre application doit pouvoir être contrôlée sans contact.

\n\n

En Kotlin, cela se résout avec focusable et l'ordre de focus (nextFocusDown, nextFocusForward).

\n\n
binding.buttonNext.nextFocusForwardId = R.id.buttonConfirm\nbinding.buttonConfirm.nextFocusDownId = R.id.buttonCancel
\n\n

Vérifiez que tous les éléments interactifs reçoivent le focus. Une erreur fréquente est le TextView avec ClickableSpan (lien dans le texte). Par défaut, il ne reçoit pas le focus. Corrigeons cela :

\n\n
binding.textWithLink.movementMethod = LinkMovement                

Blogs

Book Recommendations