Eu pesquisei bastante para ajustar o layout quando o softkeyboard está ativo e o implementei com êxito, mas o problema ocorre quando eu o uso android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
na minha tag de atividade no arquivo de manifesto.
Para isso, usei android:windowSoftInputMode="adjustPan|adjustResize|stateHidden"
com opções diferentes, mas sem sorte.
Depois disso, implementei FullScreen
programaticamente e tentei vários layouts para trabalhar, FullScreen
mas tudo em vão.
Consultei esses links e procurei muitas postagens aqui relacionadas a esse problema:
http://android-developers.blogspot.com/2009/04/updating-applications-for-on-screen.html
http://davidwparker.com/2011/08/30/android-how-to-float-a-row-above-keyboard/
Aqui está o código xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/masterContainerView"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#ffffff">
<ScrollView android:id="@+id/parentScrollView"
android:layout_width="fill_parent" android:layout_height="wrap_content">
<LinearLayout android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="vertical">
<TextView android:id="@+id/setup_txt" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Setup - Step 1 of 3"
android:textColor="@color/top_header_txt_color" android:textSize="20dp"
android:padding="8dp" android:gravity="center_horizontal" />
<TextView android:id="@+id/txt_header" android:layout_width="fill_parent"
android:layout_height="40dp" android:text="AutoReply:"
android:textColor="@color/top_header_txt_color" android:textSize="14dp"
android:textStyle="bold" android:padding="10dp"
android:layout_below="@+id/setup_txt" />
<EditText android:id="@+id/edit_message"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:text="Some text here." android:textSize="16dp"
android:textColor="@color/setting_editmsg_color" android:padding="10dp"
android:minLines="5" android:maxLines="6" android:layout_below="@+id/txt_header"
android:gravity="top" android:scrollbars="vertical"
android:maxLength="132" />
<ImageView android:id="@+id/image_bottom"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_below="@+id/edit_message" />
</LinearLayout>
</ScrollView>
<RelativeLayout android:id="@+id/scoringContainerView"
android:layout_width="fill_parent" android:layout_height="50px"
android:orientation="vertical" android:layout_alignParentBottom="true"
android:background="#535254">
<Button android:id="@+id/btn_save" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_alignParentRight="true"
android:layout_marginTop="7dp" android:layout_marginRight="15dp"
android:layout_below="@+id/edit_message"
android:text = "Save" />
<Button android:id="@+id/btn_cancel" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_marginTop="7dp"
android:layout_marginRight="10dp" android:layout_below="@+id/edit_message"
android:layout_toLeftOf="@+id/btn_save" android:text = "Cancel" />
</RelativeLayout>
</RelativeLayout>
Eu quero que os 2 botões inferiores subam quando a tecla programável aparecer na imagem.
fonte
android:windowSoftInputMode="adjustPan"
me dizer se este trabalho ..adjustResize
eadjustPan
, ao mesmo tempo, no javadoc deandroid.view.WindowManager.LayoutParams#SOFT_INPUT_ADJUST_RESIZE
: "Isso não pode ser combinado com {@link SOFT_INPUT_ADJUST_PAN}"Respostas:
Com base na solução alternativa do yghm, codifiquei uma classe de conveniência que me permite resolver o problema com uma linha (depois de adicionar a nova classe ao meu código-fonte, é claro). O one-liner é:
E a classe de implementação é:
Espero que isso ajude alguém.
fonte
return (r.bottom - r.top);
porreturn r.bottom
para que ele funcionasse no meu HTC One Mini, caso contrário, a exibição da atividade seria muito alta pelo tamanho da barra de status. Ainda não testei em outro dispositivo. Espero que possa ajudar.frameLayoutParams.height = usableHeightSansKeyboard;
tenho que usar.frameLayoutParams.height = usableHeightNow;
Se não o fizer, alguns elementos ficam fora da tela.Como a resposta já foi escolhida e o problema é conhecido como bug, pensei em adicionar uma "solução possível".
Você pode alternar para o modo tela cheia quando o teclado virtual é exibido. Isso permite que o "AdjustPan" funcione corretamente.
Em outras palavras, eu ainda uso @android: style / Theme.Black.NoTitleBar.Fullscreen como parte do tema do aplicativo e stateVisible | AdjustResize como parte do modo de entrada programável da janela de atividade, mas para que eles funcionem juntos, devo alternar o modo de tela cheia antes do teclado aparecer.
Use o seguinte código:
Desativar o modo de tela cheia
Ativar o modo de tela cheia
Nota - a inspiração veio de: Ocultando o título no modo de tela cheia
fonte
Tentei a solução com Joseph Johnson , mas, como outros, me deparei com o problema do espaço entre o conteúdo e o teclado. O problema ocorre porque o modo de entrada suave é sempre panorâmico ao usar o modo de tela cheia. Esse panorama interfere na solução de Joseph quando você ativa um campo de entrada que seria oculto pela entrada flexível.
Quando a entrada flexível é exibida, o conteúdo é exibido primeiro com base na sua altura original e depois redimensionado pelo layout solicitado pela solução de Joseph. O redimensionamento e o layout subsequente não desfazem o panorama, o que resulta na lacuna. A ordem completa dos eventos é:
Não é possível desativar o panorama, mas é possível forçar o deslocamento do panorama para 0 alterando a altura do conteúdo. Isso pode ser feito no ouvinte, porque é executado antes do pan. Definir a altura do conteúdo para a altura disponível resulta em uma experiência suave do usuário, ou seja, sem tremulações.
Eu também fiz essas mudanças. Se algum deles apresentar problemas, informe-me:
getWindowVisibleDisplayFrame
. ORect
é armazenado em cache para evitar um pouco de lixo desnecessário.Foi testado em um Nexus 5 e emuladores executando os níveis de API 16-24 com tamanhos de tela variando de pequeno a grande.
O código foi portado para o Kotlin, mas transportar minhas alterações para Java é simples. Deixe-me saber se você precisar de ajuda:
fonte
possiblyResizeChildOfContent
chamada quanto naremoveListener
chamada e, mesmo depois de atingir oremoveListener
ponto de interrupção,possiblyResizeChildOfContent
ainda está sendo chamado. Alguém mais tendo esse problema?Acabei de encontrar uma solução simples e confiável se você estiver usando a abordagem da interface do sistema ( https://developer.android.com/training/system-ui/immersive.html ).
Isso funciona quando você estiver usando
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
, por exemplo, se estiver usandoCoordinatorLayout
.Não funcionará para
WindowManager.LayoutParams.FLAG_FULLSCREEN
(Aquele com o qual você também pode definir um temaandroid:windowFullscreen
), mas é possível obter um efeito semelhante comSYSTEM_UI_FLAG_LAYOUT_STABLE
(que "tem o mesmo efeito visual" de acordo com os documentos ) e essa solução deve funcionar novamente.Eu testei no meu dispositivo executando o Marshmallow.
A chave é que os teclados programáveis também são uma das janelas do sistema (como barra de status e barra de navegação); portanto, o
WindowInsets
despachado pelo sistema contém informações precisas e confiáveis sobre ele.Para o caso de uso, como
DrawerLayout
onde estamos tentando desenhar atrás da barra de status, podemos criar um layout que ignore apenas a inserção superior e aplique a inserção inferior responsável pelo teclado virtual.Aqui está o meu costume
FrameLayout
:E para usá-lo:
Teoricamente, isso deve funcionar para qualquer dispositivo sem modificação insana, muito melhor do que qualquer invasão que tente usar um tamanho aleatório
1/3
ou1/4
de tela como referência.(Requer API 16+, mas eu estou usando a tela cheia apenas no Lollipop + para desenhar atrás da barra de status, por isso é a melhor solução nesse caso.)
fonte
Observe que
android:windowSoftInputMode="adjustResize"
não funciona quandoWindowManager.LayoutParams.FLAG_FULLSCREEN
está definido para uma atividade. Você tem duas opções.Desative o modo de tela cheia para sua atividade. A atividade não é redimensionada no modo de tela cheia. Você pode fazer isso no xml (alterando o tema da atividade) ou no código Java. Adicione as seguintes linhas no seu método onCreate ().
OU
Use uma maneira alternativa de obter o modo de tela cheia. Adicione o seguinte código ao seu método onCreate ().
Observe que o método-2 funciona apenas no Android 4.1 e superior.
fonte
Eu também tive que enfrentar esse problema e tive um trabalho em torno do qual verifiquei no HTC One, Galaxy S1, S2, S3, Note e HTC Sensation.
coloque um ouvinte de layout global na visualização raiz do seu layout
e lá verifiquei a diferença de altura e, se a diferença de altura da tela for maior que um terço da altura da tela, podemos assumir que o teclado está aberto. tirou desta resposta .
isso provavelmente não é à prova de balas e talvez em alguns dispositivos não funcione, mas funcionou para mim e espero que também o ajude.
fonte
Eu implementei a solução Joseph Johnson e funcionou bem, notei que depois de usar essa solução, às vezes a gaveta do aplicativo não fecha corretamente. Adicionei uma funcionalidade para remover o ouvinte removeOnGlobalLayoutListener quando o usuário fecha o fragmento em que os edittexts estão localizados.
usa a classe em que meus edittexts estão localizados
fonte
Adicione
android:fitsSystemWindows="true"
ao layout, e esse layout será redimensionado.fonte
Para que ele funcione com o FullScreen:
Use o plug-in do teclado iônico. Isso permite que você escute quando o teclado aparece e desaparece.
OnDeviceReady adicione estes ouvintes de evento:
A lógica:
Basicamente, se a diferença é menor, essa é a quantidade de pixels que o teclado está cobrindo da sua entrada. Portanto, se você ajustar sua div principal por isso, isso deve ser combatido.
Adicionar tempos limite à lógica diz que 300ms também devem otimizar o desempenho (pois isso permitirá que o tempo do teclado apareça.
fonte
Tentei a aula de Joseph Johnson, e funcionou, mas não atendeu às minhas necessidades. Em vez de emular o android: windowSoftInputMode = "AdjustResize", eu precisava emular o android: windowSoftInputMode = "AdjustPan".
Estou usando isso para uma visualização na web em tela cheia. Para deslocar a exibição do conteúdo para a posição correta, preciso usar uma interface javascript que forneça detalhes sobre a posição do elemento da página que está em foco e, portanto, esteja recebendo a entrada do teclado. Omiti esses detalhes, mas reescrevi a aula de Joseph Johnson. Ele fornecerá uma base muito sólida para você implementar uma panorâmica personalizada versus o redimensionamento.
fonte
Na verdade, a aparência do teclado virtual não parece afetar de
Activity
forma alguma, não importa o quewindowSoftInputMode
eu selecione noFullScreen
modo.Embora eu não tenha conseguido encontrar muita documentação sobre essa propriedade, acho que o
FullScreen
modo foi projetado para aplicativos de jogos que não exigem muito uso do teclado virtual. Se a sua atividade for uma que requer interação do usuário por meio do teclado virtual, reconsidere usar um tema que não seja o FullScreen. Você pode desativar a barra de título usando umNoTitleBar
tema. Por que você deseja ocultar a barra de notificação?fonte
Apenas mantenha como
android:windowSoftInputMode="adjustResize"
. Como ele é fornecido para manter apenas um fora de"adjustResize"
e"adjustPan"
(O modo de ajuste da janela é especificado com AdjustResize ou AdjustPan. É altamente recomendável que você sempre especifique um ou outro). Você pode encontrá-lo aqui: http://developer.android.com/resources/articles/on-screen-inputs.htmlFunciona perfeitamente para mim.
fonte
Atualmente, estou usando essa abordagem e funciona como um encanto. O truque é obter a altura do teclado de diferentes métodos no 21 acima e abaixo e usá-lo como o preenchimento inferior da nossa visualização raiz em nossa atividade. Eu assumi que seu layout não precisa de um preenchimento superior (fica abaixo da barra de status), mas, se precisar, informe-me para atualizar minha resposta.
MainActivity.java
Não se esqueça de abordar sua visualização raiz com um ID:
activity_main.xml
Espero que ajude alguém.
fonte
use apenas
android:windowSoftInputMode="adjustResize|stateHidden
como você usa o AdjustPan, em seguida, ele desativa a propriedade de redimensionamentofonte
fonte
com base em https://stackoverflow.com/a/19494006/1815624 e desejo que isso aconteça ...
ideia atualizada
combinando respostas de
Código relevante:
Fonte completa em https://github.com/CrandellWS/AndroidBug5497Workaround/blob/master/AndroidBug5497Workaround.java
velha ideia
Crie um valor estático da altura dos contêineres antes de abrir o teclado Defina a altura do contêiner com base em
usableHeightSansKeyboard - heightDifference
quando o teclado for aberto e retorne ao valor salvo ao fecharMétodos em MainActivity
Exemplo de XML do Contêiner
da mesma forma, margens podem ser adicionadas, se necessário ...
Outra consideração é o uso de preenchimento. Um exemplo disso pode ser encontrado em:
https://github.com/mikepenz/MaterialDrawer/issues/95#issuecomment-80519589
fonte
1) Crie KeyboardHeightHelper:
2) Deixe sua atividade em tela cheia:
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
3) Ouça as alterações de altura do teclado e adicione preenchimento inferior à sua exibição:
Portanto , toda vez que o teclado aparecer na tela - o preenchimento inferior da sua visualização mudará e o conteúdo será reorganizado.
fonte
Você deseja que a barra inferior fique na parte inferior da visualização, mas quando o teclado for exibido, eles deverão se mover para cima e serem colocados acima do teclado, certo?
Você pode tentar este trecho de código:
A barra inferior ficará na parte inferior da visualização e o LinearLayout que contém o ScrollView reterá o que resta da visualização depois que a barra superior / inferior e o teclado forem exibidos. Deixe-me saber se funciona para você também.
fonte
Obrigado Joseph pela sua resposta. No entanto, no método possivelmenteResizeChildOfContent (), a parte
não estava funcionando para mim, pois a parte inferior da vista ficou oculta. Então, eu tive que pegar uma variável global restoreHeight e, no construtor, inseri a última linha
e então substituí a parte mencionada anterior por
Mas não tenho idéia do por que seu código não funcionou para mim. Seria de grande ajuda se alguém pudesse esclarecer isso.
fonte
Eu estava apenas usando o modo de tela cheia para ocultar a barra de status. No entanto, quero que o aplicativo seja redimensionado quando o teclado for mostrado. Todas as outras soluções (provavelmente devido à idade da publicação) foram complicadas ou não são possíveis para o meu uso (quero evitar alterar o código Java para o saco do PhoneGap Build).
Em vez de usar a tela cheia, modifiquei meu configure para Android para não ser de tela inteira:
E adicionou o
cordova-plugin-statusbar
, via linha de comando:Quando o aplicativo é carregado, eu chamo um método no plugin para se esconder, como:
Isso funciona como um encanto. A única desvantagem real é que a barra de status é facilmente visível enquanto o aplicativo é carregado. Para minhas necessidades, isso não foi um problema.
fonte
Eu tentei todas as respostas possíveis do stackOverflow, finalmente resolvi depois de uma semana Pesquisa longa. Eu usei o layout de coordenadas e mudei isso com linearLayout e meu problema foi corrigido. Eu não sei, possivelmente, o layout de coordenadas tem bugs ou qualquer coisa meu erro.
fonte
Tentei muitas soluções, incluindo as de Joseph Johnson e Johan Stuyts. Mas, como resultado, tive um espaço em branco entre o conteúdo e o teclado em alguns dispositivos (como o Lenovo s820) em todos os casos. Então, eu fiz algumas alterações em seus códigos e finalmente obtive a solução de trabalho.
Minha ideia foi adicionar margem ao topo do conteúdo quando o teclado está sendo exibido.
Como você pode ver, adiciono 30 px à diferença porque há um pequeno espaço em branco entre a parte superior da tela e a zona de conteúdo com margem. E eu não sei de onde ela aparece, então decidi apenas reduzir as margens e agora funciona exatamente como eu precisava.
fonte
Hoje, não está funcionando o AdjustResize na edição de tela cheia é real para o Android sdk.
Das respostas que encontrei:
a solução - mas a solução mostra isso na questão da imagem:
Então eu encontrei a solução e remova a ação desnecessária:
Então, veja meu código de solução fixa no Kotlin:
Meu código de implementação de correção de bug:
fonte
Não use:
porque funciona mal. Em vez disso, use:
fonte
No meu caso, esse problema começou a acontecer depois que adicionei o Crosswalk ao meu aplicativo Cordova. Meu aplicativo não é usado em tela cheia e no android: windowSoftInputMode = "AdjustPan".
Eu já tinha o plug-in do teclado iônico no aplicativo, portanto, foi fácil detectar se o teclado estava ativo ou inativo, graças a ele:
Eu tentei todas as correções acima, mas a linha simples que acabou fazendo isso por mim foi este pouco de css:
Espero que isso poupe os poucos dias que passei nisso. :)
fonte