Présentation des événements d'entrée

Essayer Compose
Jetpack Compose est le kit d'outils d'UI recommandé pour Android. Découvrez comment utiliser la saisie tactile et les entrées dans Compose.

Sur Android, il existe plusieurs façons d'intercepter les événements liés à l'interaction d'un utilisateur avec votre application. Lorsque vous examinez les événements dans votre interface utilisateur, l'approche consiste à capturer les événements à partir de l'objet View spécifique avec lequel l'utilisateur interagit. La classe View fournit les moyens de le faire.

Dans les différentes classes View que vous utiliserez pour composer votre mise en page, vous remarquerez peut-être plusieurs méthodes de rappel publiques qui semblent utiles pour les événements d'UI. Ces méthodes sont appelées par le framework Android lorsque l'action correspondante se produit sur cet objet. Par exemple, lorsqu'un utilisateur appuie sur une vue (comme un bouton), la méthode onTouchEvent() est appelée sur cet objet. Toutefois, pour intercepter cela, vous devez étendre la classe et remplacer la méthode. Toutefois, il ne serait pas pratique d'étendre chaque objet View pour gérer un tel événement. C'est pourquoi la classe View contient également une collection d'interfaces imbriquées avec des rappels que vous pouvez définir beaucoup plus facilement. Ces interfaces, appelées écouteurs d'événements, vous permettent de capturer l'interaction de l'utilisateur avec votre UI.

Bien que vous utilisiez plus souvent les écouteurs d'événements pour écouter l'interaction de l'utilisateur, il peut arriver que vous souhaitiez étendre une classe View afin de créer un composant personnalisé. Vous souhaiterez peut-être étendre la classe Button pour créer quelque chose de plus sophistiqué. Dans ce cas, vous pourrez définir les comportements d'événement par défaut pour votre classe à l'aide des gestionnaires d'événements de la classe.

Écouteurs d'événements

Un écouteur d'événements est une interface de la classe View qui contient une seule méthode de rappel. Ces méthodes seront appelées par le framework Android lorsque la vue à laquelle le listener a été enregistré est déclenchée par l'interaction de l'utilisateur avec l'élément de l'UI.

Les interfaces d'écouteur d'événements incluent les méthodes de rappel suivantes :

onClick()
À partir de View.OnClickListener. Cette méthode est appelée lorsque l'utilisateur appuie sur l'élément (en mode tactile) ou le sélectionne à l'aide des touches de navigation ou du trackball, puis appuie sur la touche "Entrée" appropriée ou sur le trackball.
onLongClick()
À partir de View.OnLongClickListener. Cette méthode est appelée lorsque l'utilisateur appuie de manière prolongée sur l'élément (en mode tactile), ou lorsqu'il sélectionne l'élément à l'aide des touches de navigation ou du trackball, puis appuie de manière prolongée sur la touche "Entrée" appropriée ou sur le trackball (pendant une seconde).
onFocusChange()
À partir de View.OnFocusChangeListener. Cette méthode est appelée lorsque l'utilisateur accède à l'élément ou le quitte à l'aide des touches de navigation ou du trackball.
onKey()
De View.OnKeyListener. Cette méthode est appelée lorsque l'utilisateur est concentré sur l'élément et appuie sur une touche matérielle de l'appareil ou la relâche.
onTouch()
À partir de View.OnTouchListener. Cette méthode est appelée lorsque l'utilisateur effectue une action qualifiée d'événement tactile, y compris une pression, un relâchement ou tout geste de déplacement sur l'écran (dans les limites de l'élément).
onCreateContextMenu()
À partir de View.OnCreateContextMenuListener. Celle-ci est appelée lorsqu'un menu contextuel est en cours de création (à la suite d'un "clic long" prolongé). Consultez la discussion sur les menus contextuels dans le guide du développeur Menus.

Ces méthodes sont les seuls éléments de leur interface respective. Pour définir l'une de ces méthodes et gérer vos événements, implémentez l'interface imbriquée dans votre activité ou définissez-la comme classe anonyme. Ensuite, transmettez une instance de votre implémentation à la méthode View.set...Listener() correspondante. (Par exemple, appelez setOnClickListener() et transmettez-lui votre implémentation de OnClickListener.)

L'exemple ci-dessous montre comment enregistrer un écouteur de clic pour un bouton.

Kotlin

protected void onCreate(savedValues: Bundle) {
    ...
    val button: Button = findViewById(R.id.corky)
    // Register the onClick listener with the implementation above
    button.setOnClickListener { view ->
        // do something when the button is clicked
    }
    ...
}

Java

// Create an anonymous implementation of OnClickListener
private OnClickListener corkyListener = new OnClickListener() {
    public void onClick(View v) {
      // do something when the button is clicked
    }
};

protected void onCreate(Bundle savedValues) {
    ...
    // Capture our button from layout
    Button button = (Button)findViewById(R.id.corky);
    // Register the onClick listener with the implementation above
    button.setOnClickListener(corkyListener);
    ...
}

Vous pouvez également trouver plus pratique d'implémenter OnClickListener dans votre activité. Cela permet d'éviter le chargement de classe et l'allocation d'objet supplémentaires. Exemple :

Kotlin

class ExampleActivity : Activity(), OnClickListener {
  
    protected fun onCreate(savedValues: Bundle) {
        val button: Button = findViewById(R.id.corky)
        button.setOnClickListener(this)
    }

    // Implement the OnClickListener callback
    fun onClick(v: View) {
        // do something when the button is clicked
    }
}

Java

public class ExampleActivity extends Activity implements OnClickListener {
    protected void onCreate(Bundle savedValues) {
        ...
        Button button = (Button)findViewById(R.id.corky);
        button.setOnClickListener(this);
    }

    // Implement the OnClickListener callback
    public void onClick(View v) {
      // do something when the button is clicked
    }
    ...
}

Notez que le rappel onClick() dans l'exemple ci-dessus n'a aucune valeur de retour, mais que certaines autres méthodes d'écouteur d'événements doivent renvoyer un booléen. La raison dépend de l'événement. Voici pourquoi :

  • onLongClick() : renvoie une valeur booléenne indiquant si vous avez consommé l'événement et s'il ne doit pas être propagé davantage. En d'autres termes, renvoyez true pour indiquer que vous avez géré l'événement et qu'il doit s'arrêter là ; renvoyez false si vous ne l'avez pas géré et/ou si l'événement doit se poursuivre vers d'autres écouteurs de clic.
  • onKey() : renvoie une valeur booléenne indiquant si vous avez consommé l'événement et s'il ne doit pas être propagé davantage. Autrement dit, renvoyez true pour indiquer que vous avez géré l'événement et qu'il doit s'arrêter là. Renoyez false si vous ne l'avez pas géré et/ou si l'événement doit se poursuivre vers d'autres écouteurs de touches.
  • onTouch() : renvoie une valeur booléenne indiquant si votre écouteur consomme cet événement. L'important est que cet événement puisse être suivi de plusieurs actions. Ainsi, si vous renvoyez false lorsque l'événement d'action vers le bas est reçu, vous indiquez que vous n'avez pas utilisé l'événement et que vous ne vous intéressez pas non plus aux actions ultérieures de cet événement. Par conséquent, vous ne serez pas appelé pour d'autres actions dans l'événement, telles qu'un geste du doigt ou l'événement d'action vers le haut éventuel.

N'oubliez pas que les événements de touches matérielles sont toujours envoyés à la vue actuellement sélectionnée. Ils sont distribués en commençant par le haut de la hiérarchie des vues, puis en descendant jusqu'à ce qu'ils atteignent la destination appropriée. Si votre vue (ou un enfant de votre vue) est actuellement ciblée, vous pouvez voir le déplacement de l'événement via la méthode dispatchKeyEvent(). Au lieu de capturer les événements clés via votre vue, vous pouvez également recevoir tous les événements de votre activité avec onKeyDown() et onKeyUp().

De plus, lorsque vous réfléchissez à la saisie de texte pour votre application, n'oubliez pas que de nombreux appareils ne disposent que de méthodes de saisie logicielle. Ces méthodes ne sont pas nécessairement basées sur des touches. Certaines peuvent utiliser la saisie vocale, l'écriture manuscrite, etc. Même si une méthode de saisie présente une interface de type clavier, elle ne déclenchera généralement pas la famille d'événements onKeyDown(). Vous ne devez jamais créer d'UI qui nécessite des frappes spécifiques pour être contrôlée, sauf si vous souhaitez limiter votre application aux appareils dotés d'un clavier physique. En particulier, ne vous fiez pas à ces méthodes pour valider les saisies lorsque l'utilisateur appuie sur la touche Entrée. Utilisez plutôt des actions telles que IME_ACTION_DONE pour indiquer à la méthode de saisie comment votre application doit réagir, afin qu'elle puisse modifier son UI de manière pertinente. Évitez de faire des hypothèses sur le fonctionnement d'une méthode de saisie logicielle et faites-lui simplement confiance pour fournir du texte déjà mis en forme à votre application.

Remarque : Android appelle d'abord les gestionnaires d'événements, puis les gestionnaires par défaut appropriés à partir de la définition de classe. Par conséquent, le fait de renvoyer true à partir de ces écouteurs d'événements arrêtera la propagation de l'événement à d'autres écouteurs d'événements et bloquera également le rappel au gestionnaire d'événements par défaut dans la vue. Assurez-vous donc de vouloir mettre fin à l'événement lorsque vous renvoyez true.

Gestionnaires d'événements

Si vous créez un composant personnalisé à partir de View, vous pourrez définir plusieurs méthodes de rappel utilisées comme gestionnaires d'événements par défaut. Dans le document sur les composants de vue personnalisés, vous découvrirez certains des rappels courants utilisés pour la gestion des événements, y compris :

Il existe d'autres méthodes dont vous devez être conscient, qui ne font pas partie de la classe View, mais qui peuvent avoir un impact direct sur la façon dont vous gérez les événements. Par conséquent, lorsque vous gérez des événements plus complexes dans une mise en page, pensez à utiliser ces autres méthodes :

Mode Écran tactile

Lorsqu'un utilisateur navigue dans une interface utilisateur à l'aide des touches directionnelles ou d'une trackball, il est nécessaire de mettre en évidence les éléments interactifs (comme les boutons) afin qu'il puisse voir ce qui acceptera les saisies. Toutefois, si l'appareil est tactile et que l'utilisateur commence à interagir avec l'interface en la touchant, il n'est plus nécessaire de mettre en surbrillance les éléments ni de sélectionner une vue particulière. Il existe donc un mode d'interaction appelé "mode tactile".

Pour un appareil tactile, une fois que l'utilisateur touche l'écran, l'appareil passe en mode tactile. À partir de ce moment, seules les vues pour lesquelles isFocusableInTouchMode() est défini sur "true" seront focusables, comme les widgets de modification de texte. Les autres vues tactiles, comme les boutons, ne seront pas sélectionnées lorsqu'elles seront touchées. Elles déclencheront simplement leurs écouteurs de clic lorsqu'elles seront appuyées.

Chaque fois qu'un utilisateur appuie sur une touche directionnelle ou fait défiler l'écran avec un trackball, l'appareil quitte le mode tactile et recherche une vue à sélectionner. L'utilisateur peut désormais reprendre l'interaction avec l'interface utilisateur sans toucher l'écran.

L'état du mode tactile est conservé dans l'ensemble du système (toutes les fenêtres et activités). Pour interroger l'état actuel, vous pouvez appeler isInTouchMode() pour savoir si l'appareil est actuellement en mode tactile.

Gestion de la mise au point

Le framework gère les déplacements de focus de routine en réponse aux entrées utilisateur. Cela inclut le changement de focus lorsque des vues sont supprimées ou masquées, ou lorsque de nouvelles vues deviennent disponibles. Les vues indiquent leur volonté de prendre le focus via la méthode isFocusable(). Pour modifier la possibilité de prise de focus d'une vue, appelez setFocusable(). En mode tactile, vous pouvez vérifier si une vue autorise la sélection avec isFocusableInTouchMode(). Vous pouvez modifier ce paramètre dans setFocusableInTouchMode().

Sur les appareils équipés d'Android 9 (niveau d'API 28) ou version ultérieure, les activités n'attribuent pas de focus initial. Vous devez donc demander explicitement la sélection initiale, si vous le souhaitez.

Le déplacement de la sélection est basé sur un algorithme qui trouve le voisin le plus proche dans une direction donnée. Dans de rares cas, l'algorithme par défaut peut ne pas correspondre au comportement souhaité par le développeur. Dans ces situations, vous pouvez fournir des remplacements explicites avec les attributs XML suivants dans le fichier de mise en page : nextFocusDown, nextFocusLeft, nextFocusRight et nextFocusUp. Ajoutez l'un de ces attributs à la vue from à partir de laquelle le focus est supprimé. Définissez la valeur de l'attribut sur l'ID de la vue à laquelle la mise au point doit être accordée. Exemple :

<LinearLayout
    android:orientation="vertical"
    ... >
  <Button android:id="@+id/top"
          android:nextFocusUp="@+id/bottom"
          ... />
  <Button android:id="@+id/bottom"
          android:nextFocusDown="@+id/top"
          ... />
</LinearLayout>

Normalement, dans cette mise en page verticale, la navigation vers le haut à partir du premier bouton ne mènerait nulle part, pas plus que la navigation vers le bas à partir du deuxième bouton. Maintenant que le bouton du haut a défini celui du bas comme nextFocusUp (et inversement), le focus de navigation passera du haut vers le bas et du bas vers le haut.

Si vous souhaitez déclarer une vue comme pouvant être sélectionnée dans votre UI (alors qu'elle ne l'est pas traditionnellement), ajoutez l'attribut XML android:focusable à la vue, dans la déclaration de votre mise en page. Définissez la valeur true. Vous pouvez également déclarer une vue comme pouvant être sélectionnée en mode tactile avec android:focusableInTouchMode.

Pour demander qu'une vue spécifique soit mise au point, appelez requestFocus().

Pour écouter les événements de focus (être averti lorsqu'une vue reçoit ou perd le focus), utilisez onFocusChange(), comme indiqué dans la section Écouteurs d'événements.