Gérer la visibilité du mode de saisie

Lorsque le curseur de saisie se déplace à l'intérieur ou à l'extérieur d'un champ de texte modifiable, Android affiche ou masque l'entrée, telle que le clavier à l'écran, en tant que approprié. Le système décide également de la manière dont l'interface utilisateur et le champ de texte s'affichent au-dessus. le mode de saisie. Par exemple, lorsque l'espace vertical sur l'écran est le champ de texte peut occuper tout l'espace au-dessus du mode de saisie.

Pour la plupart des applications, ces comportements par défaut suffisent. Dans certains cas, mais vous pouvez avoir plus de contrôle sur la visibilité du mode de saisie son impact sur la mise en page. Dans cette leçon, vous découvrirez comment contrôler la visibilité du mode de saisie.

Afficher le clavier virtuel au début de l'activité

Bien qu'Android mette l'accent sur le premier champ de texte de votre mise en page lorsque démarre, le clavier virtuel n'est pas affiché. Ce comportement est approprié car la saisie de texte peut ne pas être la tâche principale de l'activité. Toutefois, si la saisie de texte est effectivement la tâche principale, comme dans un écran de connexion, vous souhaitez probablement que le clavier virtuel s'affiche par défaut.

Pour afficher le mode de saisie au début de l'activité, ajoutez la méthode android:windowSoftInputMode à la <activity> avec la valeur "stateVisible". Exemple :

<application ... >
    <activity
        android:windowSoftInputMode="stateVisible" ... >
        ...
    </activity>
   ...
</application>

Spécifiez la manière dont l'interface utilisateur doit répondre

Lorsque le clavier virtuel apparaît à l'écran, cela réduit l'espace disponible pour l'UI de votre application. C'est le système qui décide comment ajuster de votre UI, mais il est possible que les résultats ne soient pas corrects. Pour garantir un comportement optimal pour votre application, spécifiez la manière dont vous souhaitez que le système affiche votre UI l'espace restant.

Pour indiquer votre traitement préféré dans une activité, utilisez le Attribut android:windowSoftInputMode dans l'élément <activity> de votre fichier manifeste avec l'une des valeurs "adjust" valeurs.

Par exemple, pour vous assurer que le système redimensionne votre mise en page en fonction des ce qui permet d'accéder à tout le contenu de votre mise en page, nécessite un défilement. Utilisez "adjustResize":

<application ... >
   <activity
       android:windowSoftInputMode="adjustResize" ... >
       ...
   </activity>
   ...
</application>

Vous pouvez combiner les spécifications d'ajustement avec le clavier virtuel initial visibilité de la section précédente:

<activity
    android:windowSoftInputMode="stateVisible|adjustResize" ... >
    ...
</activity>

Il est important de spécifier "adjustResize" si votre interface utilisateur inclut des contrôles que l'utilisateur peut avoir besoin d'y accéder immédiatement après ou pendant la saisie de texte. Pour exemple, si vous utilisez une mise en page relative pour placer une barre de boutons en bas de l'écran. L'utilisation de "adjustResize" redimensionne la mise en page pour que la barre de boutons s'affiche. au-dessus du clavier virtuel.

Afficher le clavier virtuel à la demande

S'il existe une méthode dans le cycle de vie de votre activité qui vous permet de vous assurer méthode de saisie est visible, vous pouvez utiliser la InputMethodManager pour l'afficher.

Par exemple, la méthode suivante prend une View, dans laquelle l'utilisateur est censé taper quelque chose, appeler requestFocus() pour lui attribuer puis appelle showSoftInput() pour ouvrir le mode de saisie:

Kotlin

fun showSoftKeyboard(view: View) {
   if (view.requestFocus()) {
       val imm = getSystemService(InputMethodManager::class.java)
       imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
   }
}

Java

public void showSoftKeyboard(View view) {
   if (view.requestFocus()) {
       InputMethodManager imm = getSystemService(InputMethodManager.class);
       imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
   }
}

Afficher le clavier virtuel de manière fiable

Dans certaines situations, par exemple le démarrage d'une activité, Utilisation de InputMethodManager.showSoftInput() pour afficher le clavier virtuel peut empêcher l'utilisateur de voir le clavier virtuel.

La visibilité du clavier virtuel lors de l'utilisation de showSoftInput() est nécessaire aux conditions suivantes:

  • La vue doit déjà être connectée au clavier virtuel. (Ceci, à son tour, nécessite que la fenêtre soit sélectionnée et que l'éditeur pour demander le focus de la vue avec View.requestFocus()).

  • La visibilité peut également être affectée par le android:windowSoftInputMode attribut et indicateurs utilisés par showSoftInput().

Dans certains cas d'utilisation, par exemple au démarrage d'une activité, ne sont pas remplies. Le système ne considère pas la vue comme connecté au clavier virtuel, ignore l'appel showSoftInput(), et le clavier virtuel n'est pas visible par l'utilisateur.

Pour vous assurer que le clavier virtuel s'affiche correctement, vous pouvez utiliser les éléments suivants : alternatives:

  • (Recommandé) Utilisez WindowInsetsControllerCompat. Cet objet affiche le clavier virtuel pendant Activity.onCreate(), comme indiqué dans les l'extrait de code suivant. La planification de l'appel est garantie après cette période. est sélectionné.

Kotlin

editText.requestFocus()
WindowCompat.getInsetsController(window, editText)!!.show(WindowInsetsCompat.Type.ime())

Java

editText.requestFocus();
WindowCompat.getInsetsController(getWindow(), editText).show(WindowInsetsCompat.Type.ime());

Kotlin

class MyEditText : EditText() {
  ...
  override fun onWindowFocusChanged(hasWindowFocus: Boolean) {
    if (hasWindowFocus) {
      requestFocus()
      post {
        val imm: InputMethodManager = getSystemService(InputMethodManager::class.java)
        imm.showSoftInput(this, 0)
      }
    }
  }
}

Java

public class MyEditText extends EditText {
  ...
  @Override
  public void onWindowFocusChanged(boolean hasWindowFocus) {
    if (hasWindowFocus) {
      requestFocus();
      post(() -> {
        InputMethodManager imm = getSystemService(InputMethodManager.class);
        imm.showSoftInput(this, 0);
      });
    }
  }
}

Gérer les indicateurs de visibilité de l'environnement d'exécution avec soin

Lorsque vous activez/désactivez la visibilité du clavier virtuel au moment de l'exécution, veillez à ne pas transmettre certaines des valeurs d'indicateur dans ces méthodes. Par exemple, si l'application attend le clavier virtuel s'affiche lors de l'appel View.getWindowInsetsController().show(ime()) à Activity.onCreate() pendant la période démarre, les développeurs de l'application doivent veiller à ne pas définir Indicateurs SOFT_INPUT_STATE_HIDDEN ou SOFT_INPUT_STATE_ALWAYS_HIDDEN lors du lancement initial, au cas où le clavier virtuel serait masqué de manière inattendue.

Le système masque généralement automatiquement le clavier virtuel

Dans la plupart des cas, le système se charge de masquer le clavier virtuel. Ce peut correspondre à l'un des cas suivants:

  • L'utilisateur termine la tâche dans le champ de texte.
  • L'utilisateur appuie sur la touche Retour ou effectue des gestes de balayage avec la navigation Retour.
  • L'utilisateur accède à une autre application, que celle-ci a définie Options SOFT_INPUT_STATE_HIDDEN ou SOFT_INPUT_STATE_ALWAYS_HIDDEN lorsque la vue est sélectionnée.

Masquer manuellement le clavier virtuel en fonction du comportement précédent du système

Votre application doit masquer manuellement le clavier virtuel dans certaines situations, par exemple : par exemple, si le champ de texte n'est plus sélectionné View.OnFocusChangeListener.onFocusChange Utilisez cette technique à bon escient ; la fermeture du clavier virtuel nuit à l'expérience utilisateur.

Si votre application masque manuellement le clavier virtuel, vous devez savoir si le clavier virtuel a été affiché explicitement ou implicitement:

  • Le clavier virtuel est considéré comme ayant été affiché explicitement après un appel à showSoftInput().

  • À l'inverse, le clavier virtuel est considéré comme ayant été implicitement affiché dans l'une des conditions suivantes:

    • Le système a affiché le clavier virtuel lors de l'application de la android:windowSoftInputMode
    • Votre application a transmis SHOW_IMPLICIT à showSoftInput()

Normalement, hideSoftInputFromWindow() masque le clavier virtuel, quelle que soit la manière dont elle a été demandée, mais avec HIDE_IMPLICIT_ONLY. il peut se limiter à fermer uniquement un clavier virtuel demandé implicitement.

Afficher une boîte de dialogue ou une vue superposée sur le clavier virtuel

Dans certains cas, l'activité d'édition peut avoir besoin de créer un fichier non modifiable boîte de dialogue ou superposition sur le clavier virtuel.

Votre application comporte plusieurs options, décrites dans les sections suivantes.

En résumé, veillez à gérer correctement les indicateurs de fenêtre du clavier virtuel. ciblant la fenêtre de telle sorte qu'elle réponde aux attentes suivantes : concernant l'ordre vertical (z-layer) :

  • Aucun indicateur (cas normal): sous la couche du clavier virtuel, il peut recevoir du texte.
  • FLAG_NOT_FOCUSABLE : en haut de la couche du clavier virtuel, mais ne peut pas recevoir de texte.
  • FLAG_ALT_FOCUSABLE_IM : peut être sélectionné en haut de la couche du clavier virtuel, mais n'est pas connecté au clavier virtuel. Empêche également toutes les vues situées en dessous de se connecter au clavier virtuel. Cela est utile pour afficher une boîte de dialogue d'application qui n'utilise pas de texte au-dessus de la couche du clavier virtuel.
  • FLAG_NOT_FOCUSABLE et FLAG_ALT_FOCUSABLE_IM : derrière la couche du clavier virtuel, mais ne peut pas recevoir de texte.
  • FLAG_NOT_FOCUSABLE et FLAG_NOT_TOUCH_MODAL : en haut du clavier virtuel, et autoriser la conversion des événements tactiles la fenêtre sur le clavier virtuel.

Créer une boîte de dialogue

Utilisez le FLAG_ALT_FOCUSABLE_IM pour conserver la boîte de dialogue au-dessus du clavier virtuel et pour empêcher le clavier virtuel de prendre le focus:

Kotlin

val content = TextView(this)
content.text = "Non-editable dialog on top of soft keyboard"
content.gravity = Gravity.CENTER
val builder = AlertDialog.Builder(this)
  .setTitle("Soft keyboard layering demo")
  .setView(content)
mDialog = builder.create()
mDialog!!.window!!
  .addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM)
mDialog!!.show()

Java

TextView content = new TextView(this);
content.setText("Non-editable dialog on top of soft keyboard");
content.setGravity(Gravity.CENTER);
final AlertDialog.Builder builder = new AlertDialog.Builder(this)
    .setTitle("Soft keyboard layering demo")
    .setView(content);
mDialog = builder.create();
mDialog.getWindow().addFlags(FLAG_ALT_FOCUSABLE_IM);
mDialog.show();

Créer une vue en superposition

Créer une vue en superposition en spécifiant TYPE_APPLICATION_OVERLAY type de fenêtre et FLAG_ALT_FOCUSABLE_IM l'indicateur de fenêtre par l'activité ciblée sur le clavier virtuel.

Kotlin

val params = WindowManager.LayoutParams(
  width,  /* Overlay window width */
  height,  /* Overlay window height */
  WindowManager.LayoutParams.TYPE_APPLICATION, /* Overlay window type */
  WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM /* No need to allow for text input on top of the soft keyboard */
    or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,  /* Allow touch event send to soft keyboard behind the overlay */
  PixelFormat.TRANSLUCENT
)
params.title = "Overlay window"
mOverlayView!!.layoutParams = params
windowManager.addView(mOverlayView, params)

Java

WindowManager.LayoutParams params = new WindowManager.LayoutParams(
    width, /* Overlay window width */
    height, /* Overlay window height */
    TYPE_APPLICATION, /* Overlay window type */
    FLAG_ALT_FOCUSABLE_IM /* No need to allow for text input on top of the soft keyboard */
        | FLAG_NOT_TOUCH_MODAL, /* Allow touch event send to soft keyboard behind the overlay */
    PixelFormat.TRANSLUCENT);
params.setTitle("Overlay window");
mOverlayView.setLayoutParams(params);
getWindowManager().addView(mOverlayView, params);

Afficher une boîte de dialogue ou une vue sous le clavier virtuel

Il se peut que votre application doive créer une boîte de dialogue ou une fenêtre qui contient les propriétés suivantes:

  • S'affiche sous le clavier virtuel demandé par une activité d'édition afin qu'elle ne soit pas affectée par la saisie de texte.
  • La taille d'encart du clavier virtuel est modifiée ajuster la disposition de la boîte de dialogue ou de la fenêtre.

Dans ce cas, votre application comporte plusieurs options. Les sections suivantes de décrire ces options.

Créer une boîte de dialogue

Créez une boîte de dialogue en définissant les paramètres FLAG_NOT_FOCUSABLE option de fenêtre et FLAG_ALT_FOCUSABLE_IM option de fenêtre:

Kotlin

val content = TextView(this)
content.text = "Non-editable dialog behind soft keyboard"
content.gravity = Gravity.CENTER
val builder = AlertDialog.Builder(this)
  .setTitle("Soft keyboard layering demo")
  .setView(content)
mDialog = builder.create()
mDialog!!.window!!
  .addFlags(FLAG_NOT_FOCUSABLE or FLAG_ALT_FOCUSABLE_IM)
mDialog!!.show()

Java

TextView content = new TextView(this);
content.setText("Non-editable dialog behind soft keyboard");
content.setGravity(Gravity.CENTER);
final AlertDialog.Builder builder = new AlertDialog.Builder(this)
    .setTitle("Soft keyboard layering demo")
    .setView(content);

mDialog = builder.create();
mDialog.getWindow()
    .addFlags(FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM);
mDialog.show();

Créer une vue en superposition

Créez une vue en superposition en définissant à la fois les paramètres FLAG_NOT_FOCUSABLE option de fenêtre et FLAG_ALT_FOCUSABLE_IM option de fenêtre:

Kotlin

val params = WindowManager.LayoutParams(
  width,  /* Overlay window width */
  height,  /* Overlay window height */
  WindowManager.LayoutParams.TYPE_APPLICATION,  /* Overlay window type */
  WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
      or WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
  PixelFormat.TRANSLUCENT
)
params.title = "Overlay window"
mOverlayView!!.layoutParams = params
windowManager.addView(mOverlayView, params)

Java

WindowManager.LayoutParams params = new WindowManager.LayoutParams(
    width, /* Overlay window width */
    height, /* Overlay window height */
    TYPE_APPLICATION, /* Overlay window type */
    FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM,
    PixelFormat.TRANSLUCENT);
params.setTitle("Overlay window");
mOverlayView.setLayoutParams(params);
getWindowManager().addView(mOverlayView, params);