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.

Sous Android, il existe plusieurs façons d'intercepter les événements liés à l'interaction d'un utilisateur avec votre application. Lorsque vous examinez des événements dans votre interface utilisateur, l'approche consiste à capturer les événements 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 cela, vous devez étendre la classe et remplacer la méthode. Cependant, il n'est 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 utilisateur avec votre interface utilisateur.

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 souhaitez peut-être étendre la classe Button pour rendre quelque chose de plus sophistiqué. Dans ce cas, vous pouvez définir les comportements d'événements par défaut pour 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 contenant une seule méthode de rappel. Ces méthodes sont 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'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 touche l'élément (en mode tactile), ou sélectionne l'élément avec les touches de navigation ou le trackball, puis 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 touche et maintient l'élément (en mode tactile), ou sélectionne l'élément avec les touches de navigation ou le trackball, et appuie de manière prolongée sur la touche "Entrée" appropriée, ou appuie sur le trackball et le maintient enfoncé (pendant une seconde).
onFocusChange()
À partir de View.OnFocusChangeListener. Cette méthode est appelée lorsque l'utilisateur accède à l'élément ou en sort à l'aide des touches de navigation ou du trackball.
onKey()
À partir de View.OnKeyListener. Cette méthode est appelée lorsque l'utilisateur sélectionne l'élément et appuie ou libère une touche matérielle sur l'appareil.
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 autre geste de mouvement à l'écran (dans les limites de l'élément).
onCreateContextMenu()
À partir de View.OnCreateContextMenuListener. Ce procédé est appelé lors de la création d'un menu contextuel (à la suite d'un "clic long" prolongé). Consultez la discussion sur les menus contextuels dans le guide du développeur sur les menus.

Ces méthodes sont les seules 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 votre Activity. Cela permet d'éviter le chargement 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. La raison 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 être transmis plus loin. 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 que l'événement doit continuer à être diffusé sur 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 être transmis plus loin. 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 que l'événement doit continuer à être utilisé par d'autres écouteurs sur la clé.
  • onTouch() : renvoie une valeur booléenne pour indiquer si votre écouteur consomme cet événement. L'important est que cet événement puisse avoir plusieurs actions qui se succèdent. Ainsi, si vous renvoyez false lorsque l'événement d'action "vers le bas" est reçu, vous indiquez que vous n'avez pas consommé l'événement et que vous n'êtes pas non plus intéressé par les actions ultérieures de cet événement. Ainsi, vous ne serez appelé à effectuer aucune autre action dans l'événement, comme un geste avec le doigt ou l'événement d'action "vers le haut".

N'oubliez pas que les événements de touche matérielle sont toujours envoyés à la vue active. Elles sont envoyées du haut de la hiérarchie des vues vers le bas, 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 modes d'entrée logiciels. Ces méthodes ne doivent pas nécessairement être basées sur des clés ; certaines peuvent utiliser la saisie vocale, l'écriture manuscrite, etc. Même si un mode de saisie présente une interface de type clavier, il ne déclenche généralement pas la famille d'événements onKeyDown(). Vous ne devez jamais créer d'interface utilisateur qui nécessite de contrôler des pressions spécifiques sur des touches, 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 l'entrée 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-vous 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 renvoi de 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 vers le gestionnaire d'événements par défaut dans la vue. Assurez-vous donc de vouloir arrêter l'événement lorsque vous renvoyez true.

Gestionnaires d'événements

Si vous créez un composant personnalisé à partir d'une vue, vous pouvez 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 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 à l'aide de touches directionnelles ou d'un trackball, il est nécessaire de cibler des éléments exploitables (comme les boutons) afin que l'utilisateur puisse voir ce qui accepte la saisie. Toutefois, si l'appareil est doté de fonctionnalités tactiles et que l'utilisateur commence à interagir avec l'interface en appuyant dessus, il n'est plus nécessaire de mettre en surbrillance des éléments ni de sélectionner une vue particulière. Ainsi, il existe 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 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 activées lorsque l'utilisateur appuie dessus. Elles déclenchent simplement leurs écouteurs de clics lorsque l'utilisateur appuie dessus.

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

Le 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() afin de voir si l'appareil est actuellement en mode tactile.

Gérer la sélection

Le framework gère le mouvement de sélection de routine en réponse à l'entrée utilisateur. Par exemple, vous pouvez modifier le curseur lorsque des vues sont supprimées ou masquées, ou lorsque de nouvelles vues deviennent disponibles. Les vues indiquent leur volonté de se concentrer via la méthode isFocusable(). Pour modifier si une vue peut être sélectionnée, appelez setFocusable(). En mode tactile, vous pouvez demander si une vue autorise le focus 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 focus initial. Au lieu de cela, vous devez demander explicitement la sélection initiale, si vous le souhaitez.

Le mouvement de mise au point se base 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 from (depuis laquelle le curseur est placé). Définissez la valeur de l'attribut comme étant l'identifiant de la vue sur laquelle le curseur doit être placé. 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 depuis le premier bouton ne irait pas du tout, ni la navigation vers le bas à partir du second bouton. Maintenant que le bouton du haut a défini celui du bas comme nextFocusUp (et inversement), le curseur de navigation va 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 le focus d'une vue particulière, appelez requestFocus().

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