Eu preciso fazer uma coisa muito simples - descobrir se o teclado do software é mostrado. Isso é possível no Android?
516
Eu preciso fazer uma coisa muito simples - descobrir se o teclado do software é mostrado. Isso é possível no Android?
Respostas:
Nova resposta adicionada em 25 de janeiro de 2012
Desde que escrevi a resposta abaixo, alguém me informou sobre a existência do ViewTreeObserver e dos amigos, APIs que estão ocultas no SDK desde a versão 1.
Em vez de exigir um tipo de layout personalizado, uma solução muito mais simples é fornecer um ID conhecido à visualização raiz da atividade, digamos
@+id/activityRoot
, conectar um GlobalLayoutListener ao ViewTreeObserver e, a partir daí, calcular o diferencial de tamanho entre a raiz da visualização da atividade e o tamanho da janela:Usando um utilitário como:
Fácil!
Nota: Seu aplicativo deve definir esse sinalizador no Android Manifest,
android:windowSoftInputMode="adjustResize"
caso contrário, a solução acima não funcionará.RESPOSTA ORIGINAL
Sim, é possível, mas é muito mais difícil do que deveria ser.
Se eu precisar me preocupar quando o teclado aparecer e desaparecer (o que é frequente), o que faço é personalizar minha classe de layout de nível superior em uma que substitua
onMeasure()
. A lógica básica é que, se o layout estiver preenchendo significativamente menos que a área total da janela, provavelmente um teclado virtual estará aparecendo.Em seguida, na sua classe Activity ...
fonte
((ViewGroup) findViewById(android.R.id.content)).getChildAt(0)
android.R.id.content
), poderá dizer com mais confiança que, emSystem
vez de seu aplicativo, a entidade está alterando sua altura. Seria muito mais seguro para a equipe do Android nos dar uma pausa e nos informar pelo menos coisas básicas sobre a entrada do SoftKeyboard.heightDiff
sempre incluirá a altura da barra de ação. Na nova resposta que foi ignorada ao testar se essa altura é maior que alguma constante, mas 100 pixels não são suficientes para dispositivos xxhdpi como o Nexus 4. Considere converter esse valor em DPs se você realmente quiser usar esse trabalho hacky. por aí.Então, espero que isso ajude alguém.
A nova resposta que Reuben Scratton deu é ótima e muito eficiente, mas realmente só funciona se você definir o windowSoftInputMode para ajustarResize. Se você configurá-lo para ajustar o painel, ainda não é possível detectar se o teclado está visível ou não usando seu trecho de código. Para contornar isso, fiz essa pequena modificação no código acima.
fonte
TwoDScrollerView
semelhante ao stackoverflow.com/a/5224088/530513, embora com o zoom também. O filho não era umImageView
layout simples, mas personalizado (estendeRelativeLayout
), mas não conseguiu detectar o teclado usando a solução recomendada, apesar da configuraçãoandroid:windowSoftInputMode="adjustResize"
. Obrigado!ActionBar
eActionBarSherlock
. Muito obrigado! By the way, existe um métodor.height()
:) #heightDiff > root.getRootView().getHeight() / 4
É um bom valor trabalhar com dispositivos de alta resolução. 100px é muito curto. no Nexus 5 com resolução 1080x1920, 1920 - (996-75)>? 100 = 999 1920 - (1776-75)>? 100 = 219 // o teclado está ativo na galaxy s2 com 480x800 res, 800 - (800-38)>? 100 = 38800 - (410-38)>? 100 = 428 // o teclado está ativado, o número mágico 100px não é bom o suficiente.Sempre foi em termos de computador, mas essa questão ainda é incrivelmente relevante!
Então, eu peguei as respostas acima e as combinei e refinei um pouco ...
Funciona para mim :)
NOTA: Se você perceber que o DefaultKeyboardDP não se encaixa no seu dispositivo, reproduza o valor e publique um comentário para que todos saibam qual deve ser o valor ... eventualmente, obteremos o valor correto para todos os dispositivos!
Para mais detalhes, confira a implementação no Cyborg
fonte
Desculpe pela resposta tardia, mas eu criei uma turma auxiliar para lidar com eventos de abertura / fechamento com ouvintes notificadores e outras coisas úteis, pode ser que alguém ache útil:
Exemplo de uso:
fonte
getLastKeyboardHeightInPx()
não inclui a altura dessa linha. Você conhece uma maneira de levar isso em consideração também?Algumas melhorias para evitar detectar erroneamente a visibilidade do teclado virtual em dispositivos de alta densidade:
O limite da diferença de altura deve ser definido como 128 dp , não 128 pixels .
Consulte o documento de design do Google sobre Metrics and Grid , 48 dp é o tamanho confortável para o objeto de toque e 32 dp é o mínimo para os botões. O teclado virtual genérico deve incluir 4 linhas de botões, para que a altura mínima do teclado seja: 32 dp * 4 = 128 dp , o que significa que o tamanho do limite deve ser transferido para pixels multiplicando a densidade do dispositivo. Para dispositivos xxxhdpi (densidade 4), o limite de altura do teclado virtual deve ser 128 * 4 = 512 pixels.
Diferença de altura entre a vista raiz e sua área visível:
altura da vista raiz - altura da barra de status - altura do quadro visível = vista inferior da raiz - fundo visível do quadro, uma vez que a altura da barra de status é igual à parte superior do quadro visível da vista raiz.
fonte
Usei um pouco de tempo para descobrir isso ... Eu executei algumas CastExceptions, mas descobri que você pode substituir o LinearLayout no layout.xml pelo nome da classe.
Como isso:
Dessa forma, você não enfrenta nenhum problema de elenco.
... e se você não quiser fazer isso em todas as páginas, recomendo que você use "MasterPage no Android". Veja o link aqui: http://jnastase.alner.net/archive/2011/01/08/ldquomaster-pagesrdquo-in-android.aspx
fonte
A verificação da altura dos elementos não é confiável porque alguns teclados como o WifiKeyboard têm altura zero.
Em vez disso, você pode usar o resultado de retorno de chamada showSoftInput () e hideSoftInput () para verificar o status do teclado. Detalhes completos e código de exemplo em
https://rogerkeays.com/how-to-check-if-the-software-keyboard-is-shown-in-android
fonte
A idéia é que, se você precisar ocultar o teclado e verificar o estado de entrada suave ao mesmo tempo, use a seguinte solução:
Este método retorna true se o teclado foi mostrado antes de ocultar.
fonte
Descobri que uma combinação do método de @ Reuben_Scratton junto com o método de @ Yogesh parece funcionar melhor. A combinação de seus métodos produziria algo como isto:
fonte
Você pode observar a ocultação do teclado virtual usando decorView da atividade.
fonte
Em vez de assumir a diferença de codificação, eu fiz algo assim, pois eu tinha opções de menu no meu aplicativo.
fonte
Também existe solução com inserções do sistema, mas funciona apenas com
API >= 21
(Android L
). Digamos que você tenhaBottomNavigationView
, que é filhoLinearLayout
e precise ocultá-lo quando o teclado for exibido:Tudo que você precisa fazer é estender
LinearLayout
da seguinte maneira:A idéia é que, quando o teclado é mostrado, as inserções do sistema são alteradas com um
.bottom
valor bastante grande .fonte
Existe um método oculto que pode ajudar nisso
InputMethodManager.getInputMethodWindowVisibleHeight
,. Mas não sei por que está escondido.fonte
Nenhuma dessas soluções funcionará para o Lollipop como está. No Lollipop
activityRootView.getRootView().getHeight()
inclui a altura da barra de botões, enquanto a medição da vista não. Eu adaptei a melhor / mais simples solução acima para trabalhar com o Lollipop.fonte
Acabei de encontrar um bug ao usar a maioria das soluções acima que sugerem a adição de um número fixo.
S4 é tem um dpi alto que resultou na altura da barra de navegação sendo 100px, portanto, meu aplicativo pensa que o teclado está aberto o tempo todo.
Portanto, com todos os novos telefones de alta resolução sendo lançados, acredito que usar um valor codificado não é uma boa idéia a longo prazo.
Uma abordagem melhor que encontrei após alguns testes em várias telas e dispositivos foi usar porcentagem. Obtenha a diferença entre o decorView e o conteúdo do seu aplicativo e depois verifique qual é a porcentagem dessa diferença. A partir das estatísticas que obtive, a maioria das barras de navegação (independentemente do tamanho, resolução etc.) levará entre 3% a 5% da tela. Onde, como se o teclado estivesse aberto, estava ocupando entre 47% a 55% da tela.
Como conclusão, minha solução foi verificar se o diff é superior a 10%, e presumo que seja um teclado aberto.
fonte
Usei uma pequena variante da resposta de Reuban, que provou ser mais útil em determinadas circunstâncias, especialmente com dispositivos de alta resolução.
fonte
R.id.activityRoot
, você pode simplesmente usarandroid.R.id.content
exatamente o que você precisa.Sempre foi em termos de computador, mas essa questão ainda é incrivelmente relevante! Então, eu peguei as respostas acima e as combinei e refinei um pouco ...
Funciona para mim.
fonte
Tente o seguinte:
fonte
Minha resposta é basicamente a mesma que a resposta de Kachi, mas envolvi-a em uma classe auxiliar agradável para limpar a maneira como é usada em todo o meu aplicativo.
Você pode usar isso para detectar alterações no teclado em qualquer lugar do aplicativo, como este:
Nota: use apenas uma das chamadas "registrar". Todos eles funcionam da mesma forma e estão lá apenas por conveniência
fonte
você pode tentar isso, funciona muito bem para mim:
fonte
Eu estava tendo dificuldade em manter o estado do teclado ao alterar a orientação dos fragmentos em um viewpager. Não sei por que, mas parece ser instável e age de maneira diferente de uma atividade padrão.
Para manter o estado do teclado nesse caso, primeiro você deve adicionar
android:windowSoftInputMode = "stateUnchanged"
ao seuAndroidManifest.xml
. Você pode notar, no entanto, que isso realmente não resolve todo o problema - o teclado não foi aberto para mim se estivesse aberto anteriormente antes da alteração da orientação. Em todos os outros casos, o comportamento parecia estar correto.Então, precisamos implementar uma das soluções mencionadas aqui. O mais limpo que encontrei foi o de George Maisuradze - use o retorno de chamada booleano de hideSoftInputFromWindow:
Guardei esse valor no
onSaveInstanceState
método do meu Fragment e o recupereionCreate
. Então, mostrei o teclado à forçaonCreateView
se tivesse um valor detrue
(ele retorna true se o teclado estiver visível antes de realmente ocultá-lo antes da destruição do fragmento).fonte
Aqui está a minha solução e funciona. Em vez de procurar o tamanho do pixel, verifique se a altura da exibição do conteúdo mudou ou não:
fonte
Não crie nenhum código rígido. A melhor maneira é redimensionar suas visualizações enquanto estiver no Get Focus on EditText with KeyBord Show. Você pode fazer isso adicionando propriedades de redimensionamento à atividade no arquivo Manifest usando o código abaixo.
android:windowSoftInputMode="adjustResize"
fonte
Existe um método direto para descobrir isso. E, não requer nenhuma alteração de layout.
Portanto, ele também funciona no modo imersivo em tela cheia.
O truque é tentar ocultar ou mostrar o teclado virtual e capturar o resultado dessa tentativa.
Sem pânico, isso realmente não mostra ou oculta o teclado. Nós apenas pedimos o estado.
Para manter-se atualizado, você pode simplesmente repetir a operação, por exemplo, a cada 200 milissegundos, usando um manipulador.
Você encontra uma implementação aqui: https://stackoverflow.com/a/27567074/2525452
fonte
Eu acho que esse método irá ajudá-lo a descobrir se o teclado é visível ou não.
fonte
A nova resposta de Reuben Scratton (calcule o HeightDiff
int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight();
) não funcionará em atividade se você definir o modo translúcido da barra de status.se você usar barra de status translúcida,
activityRootView.getHeight()
nunca mudará o clima, o teclado virtual estará visível. sempre retornará a altura da atividade e a barra de status.Por exemplo, o Nexus 4, Android 5.0.1, definido
android:windowTranslucentStatus
como true, retornará 1184 para sempre, até mesmo os ope. Se você definirandroid:windowTranslucentStatus
como false, ele retornará Height corretamente, se for invisível, retornará 1134 (não inclui a barra de status) .Feche o ime, retornará 5xx talvez (depende da altura do ime)Eu não sei o tempo, isso é um erro, tentei 4.4.4 e 5.0.1, o resultado é o mesmo.
Portanto, até agora, a segunda resposta mais acertada, a solução da Kachi será a maneira mais segura de calcular a altura da imagem. Aqui está uma cópia:
fonte
Um método que não precisa de um LayoutListener
No meu caso, gostaria de salvar o estado do teclado antes de substituir o meu fragmento. Eu chamo o método hideSoftInputFromWindow de
onSaveInstanceState
, que fecha o teclado e me retorna se o teclado estava visível ou não.Este método é simples, mas pode alterar o estado do seu teclado.
fonte
Sei que este é um post antigo, mas acho que essa é a abordagem mais simples que conheço e meu dispositivo de teste é o Nexus 5. Não tentei em outros dispositivos. Espero que outras pessoas compartilhem sua abordagem se acharem que meu código não é bom :)
imm.hideSoftInputFromWindow retorna booleano.
Obrigado,
fonte
A função acima é o que eu uso para verificar se um teclado está visível. Se for, então eu fecho.
Abaixo mostra os dois métodos necessários.
Primeiro, defina a altura da janela viável no onCreate.
Em seguida, adicione um método booleano que obtenha a altura da janela nessa instância. Se ele não corresponder ao original (supondo que você não o mude ao longo do caminho ...), o teclado estará aberto.
Frotz!
fonte
Eu sei o quão exato você pode determinar se o teclado está oculto ou não.
Isso funciona para tablets. Quando a barra de navegação é mostrada horizontalmente.
fonte