Je dois faire une chose très simple: savoir si le clavier logiciel est affiché. Est-ce possible sur Android?
516
Je dois faire une chose très simple: savoir si le clavier logiciel est affiché. Est-ce possible sur Android?
Réponses:
NOUVELLE RÉPONSE ajoutée le 25 janvier 2012
Depuis que j'ai écrit la réponse ci-dessous, quelqu'un m'a informé de l'existence de ViewTreeObserver et de ses amis, des API qui se cachent dans le SDK depuis la version 1.
Plutôt que d'exiger un type de mise en page personnalisé, une solution beaucoup plus simple consiste à donner à la vue racine de votre activité un ID connu, par exemple
@+id/activityRoot
, raccordez un GlobalLayoutListener au ViewTreeObserver, et à partir de là, calculez la différence de taille entre la racine de la vue de votre activité et la taille de la fenêtre:Utilisation d'un utilitaire tel que:
Facile!
Remarque: Votre application doit définir ce drapeau dans le manifeste Android,
android:windowSoftInputMode="adjustResize"
sinon la solution ci-dessus ne fonctionnera pas.RÉPONSE ORIGINALE
Oui, c'est possible, mais c'est beaucoup plus difficile qu'il ne devrait l'être.
Si je dois me soucier de l'apparition et de la disparition du clavier (ce qui est assez fréquent), je personnalise ma classe de disposition de niveau supérieur en une qui remplace
onMeasure()
. La logique de base est que si la mise en page se trouve remplir considérablement moins que la surface totale de la fenêtre, alors un clavier virtuel s'affiche probablement.Ensuite, dans votre classe d'activité ...
la source
((ViewGroup) findViewById(android.R.id.content)).getChildAt(0)
android.R.id.content
), vous pourrez dire avec plus de certitude queSystem
l'entité change sa hauteur plutôt que votre application. Il serait beaucoup plus sûr pour l'équipe Android de nous donner une pause et de nous faire savoir au moins des choses de base sur l'entrée SoftKeyboard.heightDiff
inclura toujours la hauteur de la barre d'action. Dans la nouvelle réponse qui a été ignorée en testant si cette hauteur est supérieure à une constante, mais 100 pixels ne sont pas suffisants pour les appareils xxhdpi tels que le Nexus 4. Envisagez de convertir cette valeur en DP si vous voulez vraiment utiliser ce travail hacky- environ.J'espère donc que cela aide quelqu'un.
La nouvelle réponse donnée par Reuben Scratton est excellente et vraiment efficace, mais elle ne fonctionne vraiment que si vous définissez votre windowSoftInputMode sur adjustResize. Si vous le définissez sur adjustPan, il n'est toujours pas possible de détecter si le clavier est visible ou non à l'aide de son extrait de code. Pour contourner ce problème, j'ai apporté cette petite modification au code ci-dessus.
la source
TwoDScrollerView
similaire à stackoverflow.com/a/5224088/530513 bien qu'avec le zoom aussi. L'enfant n'était pas une disposition simpleImageView
mais personnalisée (étendRelativeLayout
) mais n'a pas pu détecter le clavier en utilisant la solution recommandée malgré le réglageandroid:windowSoftInputMode="adjustResize"
. Merci!ActionBar
etActionBarSherlock
. Merci beaucoup! Soit dit en passant, il existe une méthoder.height()
:)heightDiff > root.getRootView().getHeight() / 4
est une bonne valeur pour travailler avec un appareil haute résolution. 100px est trop court. dans Nexus 5 avec 1080x1920 res, 1920 - (996-75)>? 100 = 999 1920 - (1776-75)>? 100 = 219 // le clavier est en place dans la galaxie s2 avec 480x800 res, 800 - (800-38)>? 100 = 38 800 - (410-38)>? 100 = 428 // le clavier est en place donc le nombre magique 100px n'est pas assez bon.Cela a toujours été le cas en termes informatiques, mais cette question est toujours incroyablement pertinente!
J'ai donc pris les réponses ci-dessus et les ai combinées et affinées un peu ...
Travaille pour moi :)
REMARQUE: Si vous remarquez que le DefaultKeyboardDP ne correspond pas à votre appareil, jouez avec la valeur et postez un commentaire pour que tout le monde sache quelle devrait être la valeur ... nous obtiendrons finalement la valeur correcte pour s'adapter à tous les appareils!
Pour plus de détails, consultez l'implémentation sur Cyborg
la source
Désolé pour la réponse tardive, mais j'avais créé une petite classe d'aide pour gérer les événements d'ouverture / fermeture avec des auditeurs avertis et d'autres choses utiles, peut-être que quelqu'un le trouverait utile:
Exemple d'utilisation:
la source
getLastKeyboardHeightInPx()
ne comprend pas la hauteur de cette ligne. Connaissez-vous également un moyen de le prendre en compte?Quelques améliorations pour éviter de détecter à tort la visibilité du clavier logiciel sur les appareils haute densité:
Le seuil de différence de hauteur doit être défini comme 128 dp , pas 128 pixels .
Reportez-vous au document de conception Google sur les mesures et la grille , 48 dp est une taille confortable pour un objet tactile et 32 dp est un minimum pour les boutons. Le clavier virtuel générique doit comprendre 4 rangées de boutons clés, la hauteur minimale du clavier doit donc être: 32 dp * 4 = 128 dp , ce qui signifie que la taille du seuil doit être transférée aux pixels en multipliant la densité de l'appareil. Pour les périphériques xxxhdpi (densité 4), le seuil de hauteur du clavier virtuel doit être de 128 * 4 = 512 pixels.
Différence de hauteur entre la vue racine et sa zone visible:
hauteur de la vue racine - hauteur de la barre d'état - hauteur du cadre visible = bas de la vue racine - bas du cadre visible, car la hauteur de la barre d'état est égale au haut du cadre visible de la vue racine.
la source
J'ai utilisé un peu de temps pour comprendre cela ... Je l'ai exécuté quelques CastExceptions, mais j'ai compris que vous pouvez remplacer LinearLayout dans le fichier layout.xml par le nom de la classe.
Comme ça:
De cette façon, vous ne rencontrez aucun problème de distribution.
... et si vous ne voulez pas le faire sur chaque page, je vous recommande d'utiliser "MasterPage dans Android". Voir le lien ici: http://jnastase.alner.net/archive/2011/01/08/ldquomaster-pagesrdquo-in-android.aspx
la source
La vérification de la hauteur des éléments n'est pas fiable car certains claviers comme WifiKeyboard ont une hauteur nulle.
Au lieu de cela, vous pouvez utiliser le résultat du rappel de showSoftInput () et hideSoftInput () pour vérifier l'état du clavier. Détails complets et exemple de code sur
https://rogerkeays.com/how-to-check-if-the-software-keyboard-is-shown-in-android
la source
L'idée est que si vous devez masquer votre clavier et vérifier simultanément l'état de la saisie logicielle, utilisez la solution suivante:
Cette méthode renvoie true si le clavier a été affiché avant de se cacher.
la source
J'ai trouvé qu'une combinaison de la méthode de @ Reuben_Scratton avec la méthode de @ Yogesh semble fonctionner le mieux. La combinaison de leurs méthodes donnerait quelque chose comme ceci:
la source
Vous pouvez observer le masquage du clavier logiciel à l'aide de décorView de l'activité.
la source
Au lieu de supposer la différence de codage, j'ai fait quelque chose comme ça, car j'avais des options de menu dans mon application.
la source
Il existe également une solution avec des insertions système, mais cela ne fonctionne qu'avec
API >= 21
(Android L
). Supposons que vous en ayez unBottomNavigationView
,LinearLayout
et que vous devez le masquer lorsque le clavier s'affiche:Tout ce que vous devez faire est d'étendre
LinearLayout
de cette manière:L'idée est que lorsque le clavier est affiché, les insertions système sont modifiées avec une
.bottom
valeur assez importante .la source
Il y a une méthode cachée qui peut aider pour cela
InputMethodManager.getInputMethodWindowVisibleHeight
,. Mais je ne sais pas pourquoi c'est caché.la source
Aucune de ces solutions ne fonctionnera pour Lollipop en l'état. Dans Lollipop
activityRootView.getRootView().getHeight()
comprend la hauteur de la barre de boutons, tandis que la mesure de la vue ne le fait pas. J'ai adapté la solution la meilleure / la plus simple ci-dessus pour travailler avec Lollipop.la source
Je viens de rencontrer un bogue en utilisant la plupart des solutions ci-dessus qui suggèrent d'ajouter un numéro fixe.
Le S4 a un dpi élevé, ce qui fait que la hauteur de la barre de navigation est de 100 pixels, donc mon application pense que le clavier est ouvert tout le temps.
Donc, avec tous les nouveaux téléphones haute résolution sortis, je pense que l'utilisation d'une valeur codée en dur n'est pas une bonne idée à long terme.
Une meilleure approche que j'ai trouvée après quelques tests sur divers écrans et appareils était d'utiliser le pourcentage. Obtenez la différence entre decorView et le contenu de votre application et vérifiez ensuite quel est le pourcentage de cette différence. D'après les statistiques que j'ai obtenues, la plupart des barres de navigation (quelle que soit la taille, la résolution, etc.) occuperont entre 3% et 5% de l'écran. Là où, comme si le clavier était ouvert, il occupait entre 47% et 55% de l'écran.
En conclusion, ma solution était de vérifier si le différentiel est supérieur à 10%, alors je suppose que c'est un clavier ouvert.
la source
J'ai utilisé une légère variante de la réponse de Reuban, qui s'est avérée plus utile dans certaines circonstances, en particulier avec les appareils haute résolution.
la source
R.id.activityRoot
, vous pouvez simplement utiliserandroid.R.id.content
ce qui est exactement ce dont vous avez besoin.Cela a toujours été le cas pour l'ordinateur, mais cette question est toujours incroyablement pertinente! J'ai donc pris les réponses ci-dessus et les ai combinées et affinées un peu ...
Ça marche pour moi.
la source
Essaye ça:
la source
Ma réponse est fondamentalement la même que la réponse de Kachi, mais je l'ai enveloppée dans une belle classe d'aide pour nettoyer la façon dont elle est utilisée dans toute mon application.
Vous pouvez l'utiliser pour détecter les modifications du clavier n'importe où dans l'application, comme ceci:
Remarque: n'utilisez qu'un seul des appels "enregistrer". Ils fonctionnent tous de la même manière et ne sont là que pour plus de commodité
la source
vous pouvez essayer cela, fonctionne très bien pour moi:
la source
J'avais du mal à maintenir l'état du clavier lors du changement d'orientation des fragments dans un viseur. Je ne sais pas pourquoi, mais cela semble juste chancelant et agit différemment d'une activité standard.
Pour conserver l'état du clavier dans ce cas, vous devez d'abord ajouter
android:windowSoftInputMode = "stateUnchanged"
à votreAndroidManifest.xml
. Vous remarquerez peut-être, cependant, que cela ne résout pas réellement tout le problème - le clavier ne s'est pas ouvert pour moi s'il a été précédemment ouvert avant le changement d'orientation. Dans tous les autres cas, le comportement semblait correct.Ensuite, nous devons mettre en œuvre l'une des solutions mentionnées ici. Le plus propre que j'ai trouvé était celui de George Maisuradze - utilisez le rappel booléen de hideSoftInputFromWindow:
J'ai stocké cette valeur dans la
onSaveInstanceState
méthode de mon fragment et je l'ai récupéréeonCreate
. Ensuite, j'ai montré de force le clavieronCreateView
s'il avait une valeur detrue
(il retourne vrai si le clavier est visible avant de le cacher avant la destruction du fragment).la source
Voici ma solution, et cela fonctionne. Au lieu de rechercher la taille des pixels, vérifiez simplement que la hauteur de la vue du contenu a changé ou non:
la source
Ne créez pas de code dur. Le meilleur moyen est de redimensionner vos vues pendant que vous vous concentrez sur EditText avec KeyBord Show. Vous pouvez le faire en ajoutant la propriété de redimensionnement de l'activité dans le fichier manifeste à l'aide du code ci-dessous.
android:windowSoftInputMode="adjustResize"
la source
Il existe une méthode directe pour le savoir. Et, il ne nécessite aucune modification de mise en page.
Donc, cela fonctionne également en mode plein écran immersif.
L'astuce est que vous essayez de masquer ou d'afficher le clavier virtuel et de capturer le résultat de cet essai.
Pas de panique, cela ne montre ni ne masque vraiment le clavier. Nous demandons simplement l'État.
Pour rester à jour, vous pouvez simplement répéter l'opération, par exemple toutes les 200 millisecondes, à l'aide d'un gestionnaire.
Vous trouverez une implémentation ici: https://stackoverflow.com/a/27567074/2525452
la source
Je pense que cette méthode vous aidera à découvrir si le clavier est visible ou non.
la source
La nouvelle réponse de Reuben Scratton (calculer le HeightDiff
int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight();
) ne fonctionnera pas en activité si vous définissez le mode de barre d'état translucide.si vous utilisez la barre d'état translucide,
activityRootView.getHeight()
ne changera jamais la météo, le clavier logiciel est visible. il renverra toujours la hauteur de l'activité et la barre d'état.Par exemple, Nexus 4, Android 5.0.1, défini
android:windowTranslucentStatus
sur true, il renverra 1184 pour toujours, même si l'image s'est ouverte. Si vous définissezandroid:windowTranslucentStatus
sur false, il renverra la hauteur correctement, s'il est invisible, il renverra 1134 (n'inclut pas la barre d'état)Je ne sais pas s'il s'agit d'un bug, j'ai essayé 4.4.4 et 5.0.1, le résultat est le même.
Donc, jusqu'à présent, la deuxième réponse la plus acceptée, la solution de Kachi sera le moyen le plus sûr de calculer la hauteur d'IME. En voici une copie:
la source
Une méthode qui n'a pas besoin d'un LayoutListener
Dans mon cas, je voudrais sauvegarder l'état du clavier avant de remplacer mon Fragment. J'appelle la méthode hideSoftInputFromWindow à partir
onSaveInstanceState
, qui ferme le clavier et retourne - moi si le clavier est visible ou non.Cette méthode est simple mais peut changer l'état de votre clavier.
la source
Je sais que c'est un vieux post mais je pense que c'est l'approche la plus simple que je connaisse et mon appareil de test est le Nexus 5. Je ne l'ai pas essayé sur d'autres appareils. J'espère que d'autres partageront leur approche s'ils trouvent que mon code n'est pas bon :)
imm.hideSoftInputFromWindow renvoie un booléen.
Merci,
la source
La fonction ci-dessus est ce que j'utilise pour vérifier si un clavier est visible. Si c'est le cas, je le ferme.
Ci-dessous montre les deux méthodes requises.
Tout d'abord, définissez la hauteur de fenêtre réalisable dans onCreate.
Ensuite, ajoutez une méthode booléenne qui obtient la hauteur de la fenêtre à cette instance. S'il ne correspond pas à l'original (en supposant que vous ne le modifiez pas en cours de route ...), le clavier est ouvert.
Frotz!
la source
Je sais à quel point vous pouvez déterminer si le clavier est caché ou non.
Cela fonctionne pour les tablettes. Lorsque la barre de navigation est affichée horizontalement.
la source