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

Essayer Compose
Jetpack Compose est le kit d'outils d'interface utilisateur recommandé pour Android. Découvrez comment utiliser l'écran tactile et la saisie dans Compose.

Sur Android, plusieurs méthodes permettent d'intercepter les événements d'une interaction de l'utilisateur avec votre application. Lorsque vous examinez des événements dans votre interface utilisateur, l'approche consiste à les capturer à partir de l'objet View spécifique avec lequel l'utilisateur interagit. La classe View permet d'effectuer cette opération.

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'interface utilisateur. 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 (un bouton, par exemple), la méthode onTouchEvent() est appelée sur cet objet. Toutefois, pour intercepter cette requête, vous devez étendre la classe et remplacer la méthode. Cependant, il ne serait pas pratique d'étendre chaque objet View afin de 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 utilisateur avec votre UI.

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

É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 dans laquelle l'écouteur a été enregistré est déclenchée par une interaction de l'utilisateur avec l'élément dans l'interface utilisateur.

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 touche l'élément (en mode tactile) ou sélectionne l'élément avec les touches de navigation ou le trackball et appuie sur la touche "Entrée" appropriée ou appuie 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 qu'il sélectionne l'élément à l'aide des touches de navigation ou du trackball et qu'il appuie et maintient la touche "Entrée" appropriée, ou appuie de manière prolongée sur le trackball (pendant une seconde).
onFocusChange()
À partir de View.OnFocusChangeListener. Ceci est appelé lorsque l'utilisateur navigue vers ou en dehors de l'élément, à l'aide des touches de navigation ou du trackball.
onKey()
À partir de View.OnKeyListener. Cette méthode est appelée lorsque l'utilisateur est concentré sur l'élément et qu'il appuie ou libère une touche matérielle sur l'appareil.
onTouch()
À partir de View.OnTouchListener. Cette action est appelée lorsque l'utilisateur effectue une action qualifiée d'événement tactile, y compris une pression, une pression ou un geste de mouvement à l'écran (dans les limites de l'élément).
onCreateContextMenu()
À partir de View.OnCreateContextMenuListener. C'est ce qu'on appelle lorsqu'un menu contextuel est créé (suite à un "clic long" prolongé). Consultez la discussion sur les menus contextuels dans le guide du développeur Menus.

Ces méthodes sont les seuls utilisateurs 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 en tant que classe anonyme. Transmettez ensuite 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 clics 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);
    ...
}

Il peut également s'avérer plus pratique d'implémenter OnClickListener dans le cadre de votre activité. Vous éviterez ainsi la charge de classe supplémentaire et l'allocation d'objets. Par 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 pas de valeur renvoyée, mais que d'autres méthodes d'écouteur d'événements doivent renvoyer une valeur booléenne. Le motif dépend de l'événement. Voici pourquoi:

  • onLongClick() : renvoie une valeur booléenne pour indiquer si vous avez consommé l'événement et si celui-ci ne doit pas se poursuivre. Autrement dit, renvoyez true pour indiquer que vous avez géré l'événement et qu'il doit s'arrêter ici. Renvoyez false si vous ne l'avez pas géré et/ou si l'événement doit continuer avec tout autre écouteur de clic.
  • onKey() : renvoie une valeur booléenne pour indiquer si vous avez consommé l'événement et si celui-ci ne doit pas se poursuivre. Autrement dit, renvoyez true pour indiquer que vous avez géré l'événement et qu'il doit s'arrêter ici. Renvoyez false si vous ne l'avez pas géré et/ou si l'événement doit continuer avec d'autres écouteurs sur clé.
  • onTouch() : renvoie une valeur booléenne pour indiquer si votre écouteur utilise cet événement. L'important est que cet événement puisse avoir plusieurs actions qui se suivent. 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 n'êtes pas non plus intéressé par les actions ultérieures de cet événement. Ainsi, vous n'êtes appelé pour aucune autre action dans l'événement, comme un geste du doigt ou l'événement d'action "Haut" éventuel.

N'oubliez pas que les événements de touche matérielle sont toujours envoyés à la vue active. Elles sont distribuées en partant du haut de la hiérarchie des vues, puis en descendant, jusqu'à ce qu'elles atteignent la destination appropriée. Si votre vue (ou un enfant de votre vue) est actuellement active, vous pouvez voir l'événement se déplacer via la méthode dispatchKeyEvent(). Au lieu de capturer des é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 logicielles. Ces méthodes ne doivent pas nécessairement être 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éclenche généralement pas la famille d'événements onKeyDown(). Vous ne devez jamais créer une UI qui nécessite des pressions de touches spécifiques, 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 la saisie lorsque l'utilisateur appuie sur la touche Entrée. Utilisez plutôt des actions telles que IME_ACTION_DONE pour indiquer au mode de saisie comment votre application s'attend à réagir, afin qu'elle puisse modifier son UI de manière significative. Évitez les hypothèses sur le fonctionnement d'un mode de saisie logiciel et faites-lui confiance pour fournir du texte déjà formaté à 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, renvoyer la valeur true à partir de ces écouteurs d'événements met fin à la propagation de l'événement aux autres écouteurs d'événements et bloque également le rappel du 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 d'une vue, 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ée, vous découvrirez certains des rappels courants utilisés pour la gestion des événements, y compris:

Il existe d'autres méthodes que vous devez connaître. Elles ne font pas partie de la classe View, mais elles peuvent avoir un impact direct sur la façon dont vous pouvez gérer les événements. Ainsi, lorsque vous gérez des événements plus complexes dans une mise en page, envisagez ces autres méthodes:

Mode Écran tactile

Lorsqu'un utilisateur navigue dans une interface utilisateur avec des touches directionnelles ou un trackball, il est nécessaire de mettre l'accent sur les éléments interactifs (comme les boutons) afin que l'utilisateur puisse voir ce qui acceptera des entrées. Toutefois, si l'appareil dispose de fonctionnalités tactiles et que l'utilisateur commence à interagir avec l'interface en appuyant dessus, il n'est plus nécessaire de mettre des éléments en surbrillance ni de cibler une vue particulière. Il existe donc un mode d'interaction nommé "mode tactile".

Sur un appareil tactile, dès que l'utilisateur touche l'écran, il passe en mode tactile. À partir de ce moment, seules les vues pour lesquelles isFocusableInTouchMode() est défini sur "true" seront sélectionnables, comme les widgets d'édition de texte. Les autres vues sur lesquelles il est possible d'appuyer, comme les boutons, ne sont pas sélectionnées lorsque l'utilisateur appuie dessus. Elles déclenchent simplement leurs écouteurs de clic lorsque l'utilisateur appuie dessus.

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. Désormais, l'utilisateur peut reprendre son 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 toutes les activités). Pour interroger l'état actuel, vous pouvez appeler isInTouchMode() afin de voir si l'appareil est actuellement en mode tactile.

Gérer la sélection

Le framework gère les mouvements de mise au point de routine en réponse à l'entrée utilisateur. Cela inclut la modification de la sélection à mesure que des vues sont supprimées ou masquées, ou lorsque de nouvelles vues deviennent disponibles. Les vues indiquent qu'elles sont prêtes à se concentrer via la méthode isFocusable(). Pour déterminer si une vue peut être sélectionnée, appelez setFocusable(). En mode tactile, vous pouvez demander si une vue autorise la sélection avec isFocusableInTouchMode(). Vous pouvez modifier cela avec setFocusableInTouchMode().

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

Le mouvement de la mise au point 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é du 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 à partir de laquelle la recherche va quitter. Définissez la valeur de l'attribut comme l'ID de la vue à laquelle l'attention doit être donnée. Par 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 irait nulle part, ni la navigation vers le bas à partir du deuxième bouton. Maintenant que le bouton du haut a défini l'élément inférieur comme nextFocusUp (et inversement), le focus de navigation passe de haut en bas et de bas en haut.

Si vous souhaitez déclarer une vue comme sélectionnable dans votre interface utilisateur (alors qu'elle ne l'est généralement pas), ajoutez l'attribut XML android:focusable à la vue dans votre déclaration de mise en page. Définissez la valeur true. Vous pouvez également déclarer une vue comme sélectionnable en mode tactile avec android:focusableInTouchMode.

Pour demander à sélectionner une vue spécifique, appelez requestFocus().

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