Pour aider à clarifier cette folie, je voudrais commencer par m'excuser au nom de tous les utilisateurs d'Android pour le traitement carrément ridicule du clavier souple par Google. La raison pour laquelle il y a tant de réponses, toutes différentes, à la même question simple est que cette API, comme beaucoup d'autres dans Android, est horriblement conçue. Je ne vois pas de manière polie de le dire.
Je veux cacher le clavier. Je m'attends à fournir à Android la déclaration suivante : Keyboard.hide()
. La fin. Merci beaucoup. Mais Android a un problème. Vous devez utiliser le InputMethodManager
pour cacher le clavier. OK, bien, c'est l'API d'Android pour le clavier. MAIS ! Vous êtes obligé d'avoir un Context
afin d'avoir accès à l'IMM. Maintenant, nous avons un problème. Je peux vouloir cacher le clavier d'une classe statique ou utilitaire qui n'a aucune utilité ou besoin de l'IMM. Context
. ou Et, pire encore, l'IMM exige que vous spécifiiez ce que View
(ou pire encore, ce que Window
) dont vous voulez cacher le clavier.
C'est ce qui rend la dissimulation du clavier si difficile. Cher Google : Quand je cherche la recette d'un gâteau, il n'y a pas de clavier caché. RecipeProvider
sur Terre qui refuserait de me fournir la recette à moins que je ne réponde d'abord à QUI le gâteau sera mangé et où il sera mangé ! !!
Cette triste histoire se termine par l'affreuse vérité : pour cacher le clavier Android, vous devrez fournir 2 formes d'identification : une Context
et soit un View
ou un Window
.
J'ai créé une méthode utilitaire statique qui peut faire le travail TRÈS solidement, à condition que vous l'appeliez à partir d'un fichier de type Activity
.
public static void hideKeyboard(Activity activity) {
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
//Find the currently focused view, so we can grab the correct window token from it.
View view = activity.getCurrentFocus();
//If no view currently has focus, create a new one, just so we can grab a window token from it
if (view == null) {
view = new View(activity);
}
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
Sachez que cette méthode utilitaire fonctionne UNIQUEMENT lorsqu'elle est appelée à partir d'un fichier de type Activity
! La méthode ci-dessus appelle getCurrentFocus
de la cible Activity
pour récupérer le jeton de fenêtre approprié.
Mais supposons que vous vouliez cacher le clavier d'une EditText
hébergé dans un DialogFragment
? Vous ne pouvez pas utiliser la méthode ci-dessus pour cela :
hideKeyboard(getActivity()); //won't work
Cela ne fonctionnera pas car vous passerez une référence à l'objet Fragment
de l'hôte Activity
qui n'aura pas de contrôle ciblé alors que le Fragment
est montré ! Wow ! Donc, pour cacher le clavier des fragments, j'ai recours au niveau inférieur, plus commun, et plus laid :
public static void hideKeyboardFrom(Context context, View view) {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
Vous trouverez ci-dessous quelques informations supplémentaires glanées au fil du temps passé à rechercher cette solution :
À propos de windowSoftInputMode
Il y a encore un autre point de discorde dont il faut être conscient. Par défaut, Android attribue automatiquement le focus initial à la première EditText
ou la commande de mise au point dans votre Activity
. Il s'ensuit naturellement que l'InputMethod (typiquement le clavier souple) répondra à l'événement focus en s'affichant. Le site windowSoftInputMode
l'attribut dans AndroidManifest.xml
lorsqu'il est réglé sur stateAlwaysHidden
indique au clavier d'ignorer cette focalisation initiale attribuée automatiquement.
<activity
android:name=".MyActivity"
android:windowSoftInputMode="stateAlwaysHidden"/>
De manière presque incroyable, il semble ne rien faire pour empêcher le clavier de s'ouvrir lorsque vous touchez la commande (à moins que ). focusable="false"
et/ou focusableInTouchMode="false"
sont affectés à la commande). Apparemment, le paramètre windowSoftInputMode s'applique uniquement aux événements de mise au point automatique, et non aux événements de mise au point déclenchés par des événements tactiles.
Par conséquent, stateAlwaysHidden
est TRES mal nommé en effet. Il devrait peut-être s'appeler ignoreInitialFocus
à la place.
MISE À JOUR : d'autres moyens d'obtenir un jeton de fenêtre
S'il n'y a pas de vue focalisée (par exemple, cela peut arriver si vous venez de changer de fragments), il existe d'autres vues qui fourniront un jeton de fenêtre utile.
Voici des alternatives pour le code ci-dessus if (view == null) view = new View(activity);
Ceux-ci ne font pas explicitement référence à votre activité.
A l'intérieur d'une classe de fragment :
view = getView().getRootView().getWindowToken();
Étant donné un fragment fragment
en tant que paramètre :
view = fragment.getView().getRootView().getWindowToken();
En commençant par le corps de votre contenu :
view = findViewById(android.R.id.content).getRootView().getWindowToken();
MISE À JOUR 2 : Effacer le focus pour éviter de réafficher le clavier si vous ouvrez l'application en arrière-plan.
Ajoutez cette ligne à la fin de la méthode :
view.clearFocus();
18 votes
Que faire si vous n'avez qu'un seul EditText et plusieurs boutons, comme des cases à cocher et des radios ? Le seul endroit où vous avez besoin du clavier est dans l'unique EditText. Comment s'enregistrer pour savoir qu'un autre bouton a été choisi/cliqué afin de masquer le clavier ?
17 votes
Je me sens stupide. Je ne parviens pas à masquer le clavier sur ICS. J'ai essayé toutes les méthodes ici et leurs combinaisons. Pas moyen. La méthode pour le montrer fonctionne, mais je ne peux pas le cacher, peu importe ce que windw token, drapeaux cacher, paramètres manifeste ou bougies à tous les saints. Sur le clavier, je vois toujours ceci : I/LatinIME( 396) : InputType.TYPE_NULL est spécifié W/LatinIME( 396) : Unexpected input class : inputType=0x00000000 imeOptions=0x00000000
4 votes
/** * Cette méthode est utilisée pour masquer le clavier logiciel. * @param activity */ public void hideSoftKeyboard(Activity activity) { InputMethodManager inputMethodManager = (InputMethodManager)activity.getSystemService(Activity.INPUT_METHOD_SERVICE) ; inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0) ; }
0 votes
ce a fonctionné pour moi
0 votes
Avec l'augmentation de la taille et de la résolution de l'écran des appareils, le masquage du clavier virtuel devient moins important.
0 votes
Il faut jouer avec InputMethodManager avec le INPUT_METHOD_SERVICE pour gérer le clavier souple, par exemple readyandroid.wordpress.com/show-hide-Android-soft-keyboard
0 votes
Vous êtes sérieux ? Vous ne pouvez pas simplement cacher le clavier à tout moment si vous le souhaitez ? Peu importe si vous avez beaucoup de boutons, ou du texte, ou un énorme écran, demander à Android de cacher le clavier doit être une instruction unique :S