4294 votes

Comment fermer/masquer le clavier programmable Android de manière programmatique ?

J'ai un EditText et un Button dans ma mise en page.

Après avoir écrit dans le champ d'édition et cliqué sur le bouton Button Je veux masquer le clavier virtuel lorsqu'on le touche en dehors du clavier. Je suppose qu'il s'agit d'un simple morceau de code, mais où puis-je en trouver un exemple ?

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) ; }

4681voto

Reto Meier Points 55904

Vous pouvez forcer Android à masquer le clavier virtuel en utilisant l'option InputMethodManager en appelant hideSoftInputFromWindow en passant le jeton de la fenêtre contenant votre vue focalisée.

// Check if no view has focus:
View view = this.getCurrentFocus();
if (view != null) {  
    InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

Cela obligera le clavier à être caché dans toutes les situations. Dans certains cas, vous voudrez passer en InputMethodManager.HIDE_IMPLICIT_ONLY comme deuxième paramètre pour s'assurer que vous ne masquez le clavier que lorsque l'utilisateur ne l'a pas explicitement forcé à apparaître (en maintenant le menu enfoncé).

Note : Si vous voulez faire cela en Kotlin, utilisez : context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager

Syntaxe Kotlin

// Only runs if there is a view that is currently focused
this.currentFocus?.let { view ->
    val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
    imm?.hideSoftInputFromWindow(view.windowToken, 0)
}

2 votes

Maintenant getSystemService() nécessite un Context et une classe de service Class . Pour le contexte, je peux appeler requiredContext mais qu'en est-il pour la classe de service ?

1 votes

@capo11 J'ai essayé avec Application.Context.getSystemService(), donc je n'avais pas besoin de la classe de service, mais cela ne fonctionne pas.

2535voto

rmirabelle Points 822

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();

1 votes

Pourquoi avoir besoin getRootView() Pourquoi pas ? getView() seulement ?

5 votes

Une doublure : ((InputMethodManager)getContext().getSystemService(Activity.‌​INPUT_METHOD_SERVICE‌​)).hideSoftInputFrom‌​Window(getView().get‌​WindowToken(), 0);

1 votes

Récemment, nous avons enfin obtenu un moyen officiel, rétrocompatible pour ce faire

852voto

Garnet Ulrich Points 2996

Il est également utile pour masquer le clavier logiciel :

getWindow().setSoftInputMode(
    WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
);

Cette fonction peut être utilisée pour supprimer le clavier programmable jusqu'à ce que l'utilisateur touche effectivement la fenêtre d'édition de texte.

0 votes

C'est la seule qui ait fonctionné en 2020. J'ai un texte à modifier dans l'activité principale et je ne veux pas que le clavier apparaisse au démarrage de l'application.

494voto

ekjyot Points 1666

Vous devez utiliser le code suivant pour masquer le clavier logiciel :

 InputMethodManager inputManager = (InputMethodManager) this
            .getSystemService(Context.INPUT_METHOD_SERVICE);

    //check if no view has focus:
    View view = this.getCurrentFocus();
    if (view == null)
        return;

    inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);

this est l'activité.

386voto

Saurabh Pareek Points 2954

J'ai une autre solution pour cacher le clavier :

InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);

Ici passe HIDE_IMPLICIT_ONLY à la position de showFlag y 0 à la position de hiddenFlag . Il fermera de force le clavier souple.

5 votes

Vous utilisez un indicateur de masquage dans le paramètre showflags. Cela ne fonctionne que parce que les constantes utilisent les mêmes entiers. Exemple utilisant les bons drapeaux

0 votes

Testé sur Android 4.0, j'aime cette solution, parce que j'ai plusieurs textes à éditer, des boutons sur cette activité, qui peuvent avoir le focus

0 votes

Cela fonctionne pour moi, je n'ai pas de zones de texte ou quoi que ce soit qui ait vraiment le focus.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X