Sur les appareils à grand écran, les utilisateurs interagissent souvent avec les applications à l'aide d'un clavier, d'une souris, d'un pavé tactile, d'un stylet ou d'une manette de jeu. Pour autoriser votre application à accepter les entrées provenant d'appareils externes, procédez comme suit :
- Testez les fonctionnalités de base du clavier, comme la navigation via la touche de tabulation et des touches fléchées, la confirmation d'entrées de texte avec la touche Entrée, et l'utilisation de barre d'espace pour lire et mettre en pause le contenu dans les applications multimédias.
- Ajoutez des raccourcis clavier standards, le cas échéant (par exemple, Ctrl+Z pour annuler et Ctrl+S pour enregistrer).
- Testez les interactions de base de la souris telles que le clic droit pour afficher le menu contextuel, les modifications d'icône au passage de la souris, et l'utilisation de la molette ou du pavé tactile pour faire défiler les événements sur des vues personnalisées.
- Testez les périphériques d'entrée spécifiques aux applications, comme le stylet pour dessiner des applications, des manettes de jeu et des télécommandes MIDI pour les applications musicales.
- Envisagez de proposer des modes d'entrée avancés qui permettraient à l'application de se démarquer dans les environnements de bureau (par exemple, le pavé tactile comme fondu enchaîné pour les applications de DJ, la capture de souris pour les jeux et un large éventail de raccourcis clavier).
Clavier
La manière dont votre application réagit à la saisie au clavier contribue à une expérience de qualité sur grand écran. Il existe trois types de saisie au clavier : navigation, touches et raccourcis.
Navigation
La navigation au clavier est rarement implémentée dans les applications centrées sur l'écran tactile, mais les utilisateurs s'y attendent lorsqu'ils utilisent une application et qu'ils ont un clavier à leur disposition. Elle peut également être essentielle pour les utilisateurs ayant des besoins d'accessibilité spécifiques sur les téléphones, les tablettes, les appareils pliables et les ordinateurs.
Pour de nombreuses applications, la navigation via les touches fléchées et la touche de tabulation suffit. Elle est en grande partie gérée automatiquement par le framework Android. Par exemple, une vue Button
est sélectionnable par défaut, et la navigation au clavier devrait généralement fonctionner sans code supplémentaire. Afin d'activer la navigation au clavier pour les vues qui ne sont pas sélectionnables par défaut, les développeurs doivent les marquer comme telles, de manière programmatique ou au format XML, comme indiqué ci-dessous. Pour en savoir plus, consultez la section Focus Handling (Gestion des sélections).
Kotlin
yourView.isFocusable = true
Java
yourView.setFocusable(true);
Vous pouvez également définir l'attribut focusable
dans le fichier de mise en page :
android:focusable="true"
Une fois la sélection activée, le framework Android crée un mappage de navigation de toutes les vues sélectionnables en fonction de leur position. Cela fonctionne généralement normalement. Aucun effort supplémentaire n'est donc nécessaire. Lorsque le mappage par défaut n'est pas adapté aux besoins d'une application, vous pouvez le remplacer comme suit :
Kotlin
// Arrow keys yourView.nextFocusLeftId = R.id.view_to_left yourView.nextFocusRightId = R.id.view_to_right yourView.nextFocusTopId = R.id.view_above yourView.nextFocusBottomId = R.id.view_below // Tab key yourView.nextFocusForwardId = R.id.next_view
Java
// Arrow keys yourView.setNextFocusLeftId(R.id.view_to_left); yourView.setNextFocusRightId(R.id.view_to_left); yourView.setNextFocusTopId(R.id.view_to_left); yourView.setNextFocusBottomId(R.id.view_to_left); // Tab key yourView.setNextFocusForwardId(R.id.next_view);
Il est recommandé d'essayer d'accéder à toutes les fonctionnalités de votre application, avant sa compilation, à l'aide du clavier uniquement. Il devrait être facile d'accéder aux actions les plus courantes sans utiliser la souris ou la saisie tactile.
N'oubliez pas que le clavier peut être essentiel aux utilisateurs ayant des besoins d'accessibilité spécifiques.
Touches de clavier
Pour la saisie de texte qui serait gérée par un clavier virtuel à l'écran (IME) comme EditText
, les applications devraient se comporter comme prévu sur les appareils à grand écran sans nécessiter d'efforts supplémentaires de la part du développeur. Pour les touches que le framework ne peut pas anticiper, les applications doivent gérer ce comportement elles-mêmes. Cela est particulièrement vrai pour les applications avec des vues personnalisées.
Il peut s'agir d'applications de chat qui utilisent la touche Entrée pour envoyer un message, d'applications multimédias qui lancent et arrêtent la lecture avec la barre d'espace, ou de jeux qui contrôlent le mouvement avec les touches w, a, s et d.
La plupart des applications ignorent le rappel onKeyUp()
et ajoutent le comportement attendu pour chaque code clavier reçu, comme indiqué ci-dessous :
Kotlin
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean { return when (keyCode) { KeyEvent.KEYCODE_ENTER -> { sendChatMessage() true } KeyEvent.KEYCODE_SPACE -> { playOrPauseMedia() true } else -> super.onKeyUp(keyCode, event) } }
Java
@Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_ENTER) { sendMessage(); return true; } else if (KeyEvent.KEYCODE_SPACE){ playOrPauseMedia(); return true; } else { return super.onKeyUp(keyCode, event); } }
Un événement onKeyUp
se produit lorsqu'une touche est libérée. L'utilisation de ce rappel évite aux applications de devoir traiter plusieurs événements onKeyDown
si une clé est maintenue enfoncée ou si elle est libérée lentement. Les jeux et les applications qui souhaitent savoir à quel moment une touche est activée ou sur lesquels les utilisateurs doivent appuyer sur des touches du clavier peuvent rechercher l'événement onKeyDown()
et gérer les événements onKeyDown
répétés eux-mêmes.
Pour en savoir plus sur la compatibilité des claviers, consultez Handle keyboard actions (Gérer les actions du clavier).
Raccourcis
Les raccourcis Ctrl, Alt et Maj courants sont attendus lorsque vous utilisez un clavier physique. Si une application ne les implémente pas, l'expérience peut être frustrante pour les utilisateurs. Les utilisateurs avancés apprécient également les raccourcis pour les tâches fréquentes spécifiques aux applications. Les raccourcis contribuent à la facilité d'utilisation d'une application et la différencient de celles qui n'en ont pas.
Les raccourcis les plus courants sont Ctrl+S (Enregistrer), Ctrl+Z (Annuler) et Ctrl+Maj+Z (Répéter). Pour obtenir un exemple de raccourcis plus avancés, consultez la liste des touches de raccourci VLC Media Player.
Les raccourcis peuvent être mis en œuvre à l'aide de dispatchKeyShortcutEvent()
.
Toutes les combinaisons de méta-touches (Alt, Ctrl et Maj) sont alors interceptées pour un code clavier donné. Pour rechercher une méta-touche spécifique, utilisez KeyEvent.isCtrlPressed()
, KeyEvent.isShiftPressed()
, KeyEvent.isAltPressed()
ou KeyEvent.hasModifiers()
.
La séparation du code de raccourci des autres méthodes de saisie au clavier (onKeyUp()
et onKeyDown()
, par exemple) facilite la maintenance du code et permet l'acceptation par défaut des méta-touches sans avoir à implémenter manuellement les vérifications des méta-touches dans tous les cas. L'autorisation de toutes les combinaisons de méta-touches est parfois également plus pratique pour les utilisateurs habitués à différentes configurations de clavier et systèmes d'exploitation.
Kotlin
override fun dispatchKeyShortcutEvent(event: KeyEvent): Boolean { return when (event.keyCode) { KeyEvent.KEYCODE_O -> { openFile() // Ctrl+O, Shift+O, Alt+O true } KeyEvent.KEYCODE_Z-> { if (event.isCtrlPressed) { if (event.isShiftPressed) { redoLastAction() // Ctrl+Shift+Z pressed true } else { undoLastAction() // Ctrl+Z pressed true } } } else -> { return super.dispatchKeyShortcutEvent(event) } } }
Java
@Override public boolean dispatchKeyShortcutEvent(KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_O) { openFile(); // Ctrl+O, Shift+O, Alt+O return true; } else if(event.getKeyCode() == KeyEvent.KEYCODE_Z) { if (event.isCtrlPressed()) { if (event.isShiftPressed()) { redoLastAction(); return true; } else { undoLastAction(); return true; } } } return super.dispatchKeyShortcutEvent(event); }
Vous pouvez également implémenter des raccourcis dans onKeyUp()
en recherchant KeyEvent.isCtrlPressed()
, KeyEvent.isShiftPressed()
ou KeyEvent.isAltPressed()
comme ci-dessus. Cette approche est parfois plus facile à gérer si le méta-comportement correspond davantage à une modification d'un comportement d'application qu'à un raccourci
(par exemple, lorsque "W" signifie "avancer en marchant" et "Maj+W" signifie "avancer en courant").
Kotlin
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean { return when(keyCode) { KeyEvent.KEYCODE_W-> { if (event.isShiftPressed) { if (event.isCtrlPressed) { flyForward() // Ctrl+Shift+W pressed true } else { runForward() // Shift+W pressed true } } else { walkForward() // W pressed true } } else -> super.onKeyUp(keyCode, event) } }
Java
@Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_W) { if (event.isShiftPressed()) { if (event.isCtrlPressed()) { flyForward(); // Ctrl+Shift+W pressed return true; } else { runForward(); // Shift+W pressed return true; } } else { walkForward(); return true; } } return super.onKeyUp(keyCode, event); }
Stylet
De nombreux appareils à grand écran sont équipés d'un stylet, que les applications Android gèrent comme la saisie tactile. Certains appareils peuvent également disposer d'une table de dessin USB ou Bluetooth, comme Wacom Intuos. Les applications Android peuvent recevoir une entrée Bluetooth, mais ne fonctionnent pas avec les entrées USB.
Un événement de stylet est signalé comme événement tactile via View.onTouchEvent()
ou View.onGenericMotionEvent()
, et contient un objet MotionEvent.getSource()
de type SOURCE_STYLUS
.
MotionEvent
contient également des données supplémentaires :
MotionEvent.getToolType()
renvoieTOOL_TYPE_FINGER
, TOOL_TYPE_STYLUS ouTOOL_TYPE_ERASER
en fonction de l'outil qui est entré en contact avec la surface.MotionEvent.getPressure()
indique la pression physique appliquée au stylet (le cas échéant).MotionEvent.getAxisValue()
avecMotionEvent.AXIS_TILT
etMotionEvent.AXIS_ORIENTATION
permet de lire l'inclinaison et l'orientation physiques du stylet (le cas échéant).
Points historiques
Android regroupe les événements d'entrée et les distribue une fois par frame. Un stylet peut signaler des événements avec une fréquence beaucoup plus élevée que l'écran. Lors de la création d'applications de dessin, il est important de rechercher les événements récents à l'aide des API getHistorical
:
MotionEvent.getHistoricalX()
MotionEvent.getHistoricalY()
MotionEvent.getHistoricalPressure()
MotionEvent.getHistoricalAxisValue()
Refus de la paume de la main
Lorsque les utilisateurs dessinent, écrivent ou interagissent avec votre application à l'aide d'un stylet, ils touchent parfois l'écran avec la paume de leur main. L'événement tactile (défini sur ACTION_DOWN
ou ACTION_POINTER_DOWN
) peut être signalé à votre application avant que le système ne le reconnaisse et n'ignore la pression involontaire via la paume de la main.
Android annule les événements tactiles de la paume de la main en envoyant un MotionEvent
. Si votre application reçoit ACTION_CANCEL
, annulez le geste. Si votre application reçoit une erreur ACTION_POINTER_UP
, vérifiez si FLAG_CANCELED
est défini. Si c'est le cas, annulez le geste.
Ne recherchez pas uniquement FLAG_CANCELED
. Depuis Android 13, pour plus de commodité, le système définit FLAG_CANCELED
pour les événements ACTION_CANCEL
, ce qui n'est pas le cas des versions précédentes.
Android 12
Sur Android 12 (niveau d'API 32) et versions antérieures, la détection du refus de la paume de la main n'est possible que pour les événements tactiles à un seul pointeur. Si une pression via la paume de la main est le seul pointeur, le système annule l'événement en définissant ACTION_CANCEL
sur l'objet d'événement de mouvement.
Si les autres pointeurs impliquent une pression, le système définit ACTION_POINTER_UP
, ce qui est insuffisant pour détecter le refus de la paume de la main.
Android 13
Sur Android 13 (niveau d'API 33) ou version ultérieure, si une pression via la paume de la main est le seul pointeur, le système annule l'événement en définissant ACTION_CANCEL
et FLAG_CANCELED
sur l'objet d'événement de mouvement. Si les autres pointeurs impliquent une pression, le système définit ACTION_POINTER_UP
et FLAG_CANCELED
.
Chaque fois que votre application reçoit un événement de mouvement avec ACTION_POINTER_UP
, recherchez FLAG_CANCELED
pour déterminer si l'événement indique un refus de la paume de la main (ou une autre annulation d'événement).
Applications de prise de notes
ChromeOS utilise un intent spécial qui présente aux utilisateurs les applications de prise de notes inscrites en tant que telles. Pour inscrire une application en tant qu'application de prise de notes, ajoutez le code suivant au fichier manifeste Android :
<intent-filter>
<action android:name="org.chromium.arc.intent.action.CREATE_NOTE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
Lorsqu'une application est inscrite, l'utilisateur peut la sélectionner comme application de prise de notes par défaut. Lorsqu'une nouvelle note est demandée, l'application doit créer une note vide prête à être saisie par le stylet. Lorsque l'utilisateur souhaite annoter une image (par exemple, une capture d'écran ou une image téléchargée), l'application se lance avec ClipData
et contient un ou plusieurs éléments avec des URI content://
. L'application doit créer une note qui utilise la première image jointe comme image d'arrière-plan et passer dans un mode permettant à l'utilisateur de dessiner à l'écran avec un stylet.
Tester les intents de prise de notes sans stylet
Pour vérifier si une application répond correctement aux intents de prise de notes sans stylet actif, utilisez la méthode suivante afin d'afficher les options de prise de notes sur ChromeOS :
- Activez le mode développeur et rendez l'appareil accessible en écriture.
- Appuyez sur Ctrl+Alt+F2 pour ouvrir un terminal.
- Exécutez la commande
sudo vi /etc/chrome_dev.conf
. - Appuyez sur
i
pour effectuer des modifications, puis ajoutez--ash-enable-palette
à une nouvelle ligne à la fin du fichier - Pour enregistrer, appuyez sur Échap, puis saisissez :, w, q et appuyez sur Entrée.
- Appuyez sur Ctrl+Alt+F1 pour revenir à l'interface utilisateur ChromeOS standard.
- Déconnectez-vous, puis reconnectez-vous.
Un menu de stylet devrait maintenant s'afficher sur l'étagère :
- Appuyez sur le bouton du stylet situé sur l'étagère, puis sélectionnez Nouvelle note. Une note de dessin vide devrait s'afficher.
- Prenez une capture d'écran. À partir de l'étagère, sélectionnez Bouton du stylet > Capturer l'écran ou téléchargez une image. L'option "Annoter l'image" devrait s'afficher dans la notification. Celle-ci devrait lancer l'application avec l'image prête à être annotée.
Compatibilité avec la souris et le pavé tactile
La plupart des applications ne doivent généralement gérer que trois événements axés sur les grands écrans : effectuer un clic droit, pointer le curseur et glisser-déposer.
Effectuer un clic droit
Toutes les actions qui entraînent l'affichage d'un menu contextuel par une application, comme l'appui prolongé sur un élément de la liste, doivent également réagir aux événements de clic droit. Pour gérer ces événements, les applications doivent enregistrer un élément View.OnContextClickListener
.
Pour découvrir comment créer un menu contextuel, consultez Creating Contextual Menus (Créer des menus contextuels).
Kotlin
yourView.setOnContextClickListener { showContextMenu() true }
Java
yourView.setOnContextClickListener(v -> { showContextMenu(); return true; });
Pointer le curseur
Pour rendre leurs mises en page d'application plus fluides et plus faciles à utiliser, les développeurs peuvent gérer les événements de pointage. Cela est particulièrement vrai pour les vues personnalisées. Voici les deux exemples les plus courants :
- Modifier l'icône du pointeur de la souris pour indiquer aux utilisateurs si un élément a un comportement interactif, par exemple s'il est cliquable ou modifiable
- Ajouter un retour visuel aux éléments d'une longue liste ou grille lorsque le pointeur passe dessus
Kotlin
// Change the icon to a "hand" pointer on hover, // Highlight the view by changing the background. yourView.setOnHoverListener { view, _ -> addVisualHighlighting(true) view.pointerIcon = PointerIcon.getSystemIcon(view.context, PointerIcon.TYPE_HAND) false // listener did not consume the event. }
Java
yourView.setOnHoverListener((view, event) -> { addVisualHighlighting(true); view.setPointerIcon(PointerIcon .getSystemIcon(view.getContext(), PointerIcon.TYPE_HAND)); return true; });
Glisser-déposer
Dans un environnement multifenêtre, les utilisateurs s'attendent à pouvoir glisser-déposer des éléments entre les applications. Cela est le cas pour les ordinateurs, les tablettes, les téléphones et les pliables en mode écran partagé.
Les développeurs doivent déterminer si les utilisateurs sont susceptibles de faire glisser des éléments dans leur application. Voici quelques exemples courants de cas d'utilisation : les éditeurs de photos qui reçoivent des photos, les lecteurs audio qui reçoivent des fichiers audio et les programmes de dessin qui reçoivent des photos.
Pour permettre de glisser-déposer des éléments, consultez la documentation Android sur la fonctionnalité Glisser-déposer, et consultez cet article du blog ChromeOS.
Remarques concernant ChromeOS
- N'oubliez pas de demander l'autorisation via
requestDragAndDropPermissions
pour permettre l'accès des éléments que l'utilisateur fait glisser depuis l'extérieur de l'application. - Un élément doit être associé à l'indicateur
View.DRAG_FLAG_GLOBAL
pour pouvoir être glissé vers d'autres applications.
Compatibilité avancée avec les pointeurs
Les applications qui gèrent les commandes avancées de la souris et du pavé tactile doivent respecter la documentation Android concernant View.onGenericMotionEvent()
et utiliser MotionEvent.getSource()
pour faire la distinction entre SOURCE_MOUSE
et SOURCE_TOUCHSCREEN
.
Examinez MotionEvent
pour mettre en œuvre le comportement requis :
- Le mouvement génère des événements
ACTION_HOVER_MOVE
. - Les boutons génèrent des événements
ACTION_BUTTON_PRESS
etACTION_BUTTON_RELEASE
. Vous pouvez également vérifier l'état actuel de tous les boutons de la souris ou du pavé tactile avecgetButtonState()
. - Le défilement de la molette de la souris génère des événements
ACTION_SCROLL
.
Manettes de jeu
Certains appareils Android à grand écran acceptent jusqu'à quatre manettes de jeu. Les développeurs doivent utiliser les API de manette de jeu Android standards pour les gérer (consultez Support game controllers [Prendre en charge les manettes de jeu]).
Les boutons sont mis en correspondance avec des valeurs communes suivant un mappage commun. Malheureusement, tous les fabricants de manettes de jeu ne suivent pas les mêmes conventions de mappage. Vous offrirez une bien meilleure expérience si vous autorisez les utilisateurs à sélectionner différents mappages de manettes populaires. Pour en savoir plus, consultez la section Process gamepad button presses (Traiter les pressions sur les boutons d'une manette de jeu).
Mode de conversion d'entrée
ChromeOS offre un mode de conversion d'entrée par défaut. Pour la plupart des applications Android, ce mode permet aux applications de fonctionner comme prévu dans un environnement de bureau. Par exemple, il permet l'activation automatique du défilement à deux doigts sur le pavé tactile, le défilement de la molette de la souris et le mappage des coordonnées brutes de l'écran avec les coordonnées de la fenêtre. En règle générale, les développeurs d'applications n'ont pas besoin d'implémenter ces comportements eux-mêmes.
Si une application met en œuvre un comportement de saisie personnalisé, par exemple si vous définissez une action personnalisée de pincement avec deux doigts sur le pavé tactile, ou si ces conversions d'entrée ne fournissent pas les événements d'entrée attendus par l'application, vous pouvez désactiver la conversion d'entrée en ajoutant la balise suivante au fichier manifeste Android :
<uses-feature
android:name="android.hardware.type.pc"
android:required="false" />
Ressources supplémentaires
Recommandations personnalisées
- Remarque : Le texte du lien s'affiche lorsque JavaScript est désactivé
- Améliorer la prise en charge des stylets dans une application Android
- Éditeurs de texte personnalisés
- Compatibilité avec les tablettes et les grands écrans