Lorsque la sélection de la saisie se déplace à l'intérieur ou en dehors d'un champ de texte modifiable, Android affiche ou masque l'entrée, comme le clavier à l'écran, selon les besoins. Le système décide également de la manière dont votre interface utilisateur et le champ de texte apparaissent au-dessus du mode de saisie. Par exemple, lorsque l'espace vertical à l'écran est limité, le champ de texte peut remplir tout l'espace au-dessus de la méthode de saisie.
Pour la plupart des applications, ces comportements par défaut suffisent. Toutefois, dans certains cas, vous souhaiterez peut-être mieux contrôler la visibilité de la méthode de saisie et son impact sur la mise en page. Cette leçon explique comment contrôler la visibilité du mode de saisie et y répondre.
Afficher le clavier virtuel au début de l'activité
Bien qu'Android place le curseur sur le premier champ de texte de votre mise en page au début de l'activité, il n'affiche pas le clavier virtuel. 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 souhaiterez probablement que le clavier virtuel s'affiche par défaut.
Pour afficher le mode de saisie au début de l'activité, ajoutez l'attribut android:windowSoftInputMode
à l'élément <activity>
avec la valeur "stateVisible"
. Par exemple :
<application ... >
<activity
android:windowSoftInputMode="stateVisible" ... >
...
</activity>
...
</application>
Spécifiez la manière dont votre UI doit répondre
Lorsque le clavier virtuel apparaît à l'écran, il réduit l'espace disponible pour l'interface utilisateur de votre application. Le système décide de la manière d'ajuster la partie visible de votre interface utilisateur, mais il peut ne pas fonctionner correctement. Pour garantir un comportement optimal de votre application, spécifiez la manière dont vous souhaitez que le système affiche votre UI dans l'espace restant.
Pour déclarer votre traitement préféré dans une activité, utilisez l'attribut android:windowSoftInputMode
dans l'élément <activity>
de votre fichier manifeste avec l'une des valeurs "adjust".
Par exemple, pour vous assurer que le système redimensionne votre mise en page en fonction de l'espace disponible, ce qui permet d'accéder à l'ensemble de son contenu, même s'il nécessite un défilement, utilisez "adjustResize"
:
<application ... >
<activity
android:windowSoftInputMode="adjustResize" ... >
...
</activity>
...
</application>
Vous pouvez combiner la spécification d'ajustement avec la spécification de visibilité initiale du clavier virtuel de la section précédente:
<activity
android:windowSoftInputMode="stateVisible|adjustResize" ... >
...
</activity>
La spécification de "adjustResize"
est importante si votre interface utilisateur inclut des commandes auxquelles l'utilisateur peut avoir besoin d'accéder immédiatement après ou pendant la saisie de texte. Par exemple, si vous utilisez une mise en page relative pour placer une barre de boutons en bas de l'écran, "adjustResize"
redimensionne la mise en page afin que la barre de boutons apparaisse au-dessus du clavier virtuel.
Afficher le clavier virtuel à la demande
Si le cycle de vie de votre activité comporte une méthode pour laquelle vous souhaitez vous assurer que le mode d'entrée est visible, vous pouvez l'afficher à l'aide de InputMethodManager
.
Par exemple, la méthode suivante utilise un objet View
dans lequel l'utilisateur est censé saisir quelque chose, appelle requestFocus()
pour le cibler, puis 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 certains cas, par exemple au démarrage d'une activité, l'utilisation de InputMethodManager.showSoftInput()
pour afficher le clavier virtuel peut empêcher l'utilisateur de voir le clavier virtuel.
La visibilité du clavier virtuel lorsque vous utilisez showSoftInput()
dépend des conditions suivantes:
La vue doit déjà être connectée au clavier virtuel. (à son tour, la fenêtre doit être sélectionnée et la vue de l'éditeur doit demander la sélection de la vue avec
View.requestFocus()
).La visibilité peut également être affectée par l'attribut
android:windowSoftInputMode
et les indicateurs utilisés parshowSoftInput()
.
Dans certains cas d'utilisation, par exemple au démarrage d'une activité, certaines de ces conditions requises ne sont pas remplies. Le système ne considère pas la vue comme connectée au clavier virtuel, ignore l'appel showSoftInput()
et l'utilisateur ne peut pas voir le clavier virtuel.
Pour vous assurer que le clavier virtuel s'affiche de manière fiable, vous pouvez utiliser les alternatives suivantes:
- (Recommandé) Utilisez
WindowInsetsControllerCompat
. Cet objet affiche le clavier virtuel pendantActivity.onCreate()
, comme indiqué dans l'extrait de code suivant. La planification de l'appel est garantie une fois que la fenêtre est sélectionnée.
Kotlin
editText.requestFocus() WindowCompat.getInsetsController(window, editText)!!.show(WindowInsetsCompat.Type.ime())
Java
editText.requestFocus(); WindowCompat.getInsetsController(getWindow(), editText).show(WindowInsetsCompat.Type.ime());
- Publiez un exécutable. Cela garantit que votre application attend de recevoir l'événement de sélection de fenêtre de
View.onWindowFocusChanged()
avant d'appelershowSoftInput()
.
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 valeurs d'indicateurs à ces méthodes. Par exemple, si l'application s'attend à ce que le clavier virtuel s'affiche lors de l'appel de View.getWindowInsetsController().show(ime())
dans Activity.onCreate()
pendant le démarrage de l'activité, les développeurs de l'application doivent veiller à ne pas définir d'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 automatiquement le clavier virtuel
Dans la plupart des cas, le système dispose de poignées pour masquer le clavier virtuel. Voici les différents cas de figure possibles:
- 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 vers l'arrière.
- L'utilisateur accède à une autre application qui a défini des indicateurs
SOFT_INPUT_STATE_HIDDEN
ouSOFT_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 le clavier virtuel manuellement dans certaines situations, par exemple lorsque le champ de texte perd son focus dans View.OnFocusChangeListener.onFocusChange
. Utilisez cette technique judicieusement. La fermeture du clavier virtuel nuit à l'expérience utilisateur de manière inattendue.
Si votre application masque manuellement le clavier virtuel, vous devez savoir si celui-ci a été affiché explicitement ou implicitement:
Le clavier virtuel est considéré comme ayant été explicitement affiché après un appel à
showSoftInput()
.À l'inverse, le clavier virtuel est considéré comme ayant été affiché implicitement dans l'une des conditions suivantes:
- Le système a affiché le clavier virtuel lors de l'application de
android:windowSoftInputMode
. - Votre application a transmis
SHOW_IMPLICIT
àshowSoftInput()
.
- Le système a affiché le clavier virtuel lors de l'application de
Normalement, hideSoftInputFromWindow()
masque le clavier virtuel, quelle que soit la façon dont il a été demandé, mais avec HIDE_IMPLICIT_ONLY
, il peut se limiter à ignorer uniquement un clavier virtuel demandé implicitement.
Afficher une boîte de dialogue ou une vue en superposition sur le clavier virtuel
Dans certains cas, l'activité de l'éditeur peut avoir besoin de créer une boîte de dialogue ou une fenêtre de superposition non modifiable au-dessus du clavier virtuel.
Votre application comporte plusieurs options, décrites dans les sections suivantes.
En résumé, assurez-vous de gérer correctement les indicateurs de fenêtre du clavier virtuel ciblant la fenêtre afin qu'elle réponde aux attentes suivantes en matière d'ordre vertical (couche z) :
- Aucun indicateur (cas normal): derrière la couche du clavier virtuel et 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
: en haut de la couche du clavier virtuel, peut être sélectionné, 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 la saisie de texte au-dessus de la couche du clavier virtuel.FLAG_NOT_FOCUSABLE
etFLAG_ALT_FOCUSABLE_IM
: situé derrière la couche du clavier virtuel, mais ne peuvent pas recevoir de texte.FLAG_NOT_FOCUSABLE
etFLAG_NOT_TOUCH_MODAL
: en haut du clavier virtuel, cette option permet aux événements tactiles de passer "à travers" la fenêtre jusqu'au clavier virtuel.
Créer une boîte de dialogue
Utilisez l'indicateur de fenêtre de dialogue FLAG_ALT_FOCUSABLE_IM
pour que la boîte de dialogue reste au-dessus du clavier virtuel et que celui-ci ne soit pas sélectionné:
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éez une vue en superposition spécifiant le type de fenêtre TYPE_APPLICATION_OVERLAY
et l'indicateur de fenêtre FLAG_ALT_FOCUSABLE_IM
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
Votre application devra peut-être créer une boîte de dialogue ou une fenêtre comportant les propriétés suivantes:
- Apparaît sous le clavier virtuel demandé par une activité d'éditeur, de sorte qu'elle n'est pas affectée par la saisie de texte.
- Reste informé des modifications apportées à la taille des encarts du clavier virtuel afin d'ajuster la mise en page de la boîte de dialogue ou de la fenêtre.
Dans ce cas, votre application dispose de plusieurs options. Les sections suivantes décrivent ces options.
Créer une boîte de dialogue
Créez une boîte de dialogue en définissant à la fois l'option de fenêtre FLAG_NOT_FOCUSABLE
et l'option de fenêtre FLAG_ALT_FOCUSABLE_IM
:
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 l'option de fenêtre FLAG_NOT_FOCUSABLE
et l'option de fenêtre FLAG_ALT_FOCUSABLE_IM
:
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);