Quando o foco de entrada entra ou sai de um campo de texto editável, o Android mostra ou oculta a entrada, como o teclado na tela, conforme adequado. O sistema também decide como a interface e o campo de texto aparecem acima do método de entrada. Por exemplo, quando o espaço vertical na tela é restrito, o campo de texto pode preencher todo o espaço acima do método de entrada.
Para a maioria dos apps, esses comportamentos padrão são suficientes para atender a todas as necessidades. Em alguns casos, você pode querer mais controle sobre a visibilidade do método de entrada e como ele afeta o layout. Esta lição explica como controlar e responder à visibilidade do método de entrada.
Mostrar o teclado de software quando a atividade iniciar
Embora o Android direcione o foco para o primeiro campo de texto do layout quando a atividade é iniciada, ele não mostra o teclado de software. Esse comportamento é adequado porque a inserção de texto pode não ser a tarefa principal na atividade. No entanto, se a inserção de texto for de fato a tarefa principal, como em uma tela de login, é provável que o teclado de software apareça por padrão.
Para mostrar o método de entrada quando a atividade iniciar, adicione o atributo
android:windowSoftInputMode
ao elemento
<activity>
com o valor "stateVisible"
. Por exemplo:
<application ... >
<activity
android:windowSoftInputMode="stateVisible" ... >
...
</activity>
...
</application>
Especificar como sua IU deve responder
Quando o teclado de software aparece na tela, ele reduz a quantidade de espaço disponível para a interface do app. O sistema decide como ajustar a parte visível da sua interface, mas pode não acertar. Para garantir o melhor comportamento para o app, especifique como você quer que o sistema mostre a interface no espaço restante.
Para declarar seu tratamento preferido em uma atividade, use o
atributo android:windowSoftInputMode
no elemento <activity>
do manifesto
com um dos valores de "ajuste".
Por exemplo, para garantir que o sistema redimensione o layout para o espaço
disponível, o que mantém todo o conteúdo do layout acessível, mesmo que seja
necessário rolar a tela, use "adjustResize"
:
<application ... >
<activity
android:windowSoftInputMode="adjustResize" ... >
...
</activity>
...
</application>
É possível combinar a especificação de ajuste com a especificação de visibilidade inicial do teclado de software da seção anterior:
<activity
android:windowSoftInputMode="stateVisible|adjustResize" ... >
...
</activity>
É importante especificar "adjustResize"
caso a interface inclua controles que o
usuário pode precisar acessar imediatamente após ou durante a realização da entrada de texto. Por
exemplo, se você usa um layout relativo para colocar uma barra de botões na parte de baixo da
tela, o uso de "adjustResize"
redimensiona o layout para que a barra de botões apareça
acima do teclado de software.
Mostrar o teclado de software sob demanda
Se houver um método no ciclo de vida da sua atividade em que você queira garantir que o
método de entrada fique visível, use
InputMethodManager
para mostrar isso.
Por exemplo, o método a seguir usa uma
View
em que é esperado que o usuário
digite algo, chama
requestFocus()
para focar
e chama showSoftInput()
para abrir o método de entrada:
Kotlin
fun showSoftKeyboard(view: View) { if (view.requestFocus()) { val imm = getSystemService(InputMethodManager::class.java) imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT) } }
Java
public void showSoftKeyboard(View view) { if (view.requestFocus()) { InputMethodManager imm = getSystemService(InputMethodManager.class); imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT); } }
Exibição confiável do teclado de software
Há determinadas situações, como quando uma atividade é iniciada, em que
o uso de InputMethodManager.showSoftInput()
para exibir o teclado de software
pode fazer com que o teclado de software não fique visível para o usuário.
A visibilidade do teclado de software ao usar showSoftInput()
depende
das seguintes condições:
A visualização já precisa estar conectada ao teclado de software. Isso, por sua vez, exige que a janela seja focada e que a visualização do editor solicite o foco com
View.requestFocus()
.A visibilidade também pode ser afetada pelo atributo
android:windowSoftInputMode
e pelas sinalizações usadas peloshowSoftInput()
.
Em determinados casos de uso, como quando uma atividade é iniciada, algumas dessas
condições obrigatórias não são atendidas. O sistema não considera a visualização como
conectada ao teclado de software, ignora a chamada showSoftInput()
e o teclado de software não fica visível para o usuário.
Para garantir que o teclado de software seja mostrado de forma confiável, é possível usar as seguintes alternativas:
- (Recomendado) Use
WindowInsetsControllerCompat
. Esse objeto mostra o teclado de software duranteActivity.onCreate()
, conforme mostrado no snippet de código abaixo. A chamada será agendada após o foco da janela.
Kotlin
editText.requestFocus() WindowCompat.getInsetsController(window, editText)!!.show(WindowInsetsCompat.Type.ime())
Java
editText.requestFocus(); WindowCompat.getInsetsController(getWindow(), editText).show(WindowInsetsCompat.Type.ime());
- Publique um executável. Isso garante que o app aguarde até receber o
evento de foco da janela de
View.onWindowFocusChanged()
antes de chamarshowSoftInput()
.
Kotlin
class MyEditText : EditText() { ... override fun onWindowFocusChanged(hasWindowFocus: Boolean) { if (hasWindowFocus) { requestFocus() post { val imm: InputMethodManager = getSystemService(InputMethodManager::class.java) imm.showSoftInput(this, 0) } } } }
Java
public class MyEditText extends EditText { ... @Override public void onWindowFocusChanged(boolean hasWindowFocus) { if (hasWindowFocus) { requestFocus(); post(() -> { InputMethodManager imm = getSystemService(InputMethodManager.class); imm.showSoftInput(this, 0); }); } } }
Gerencie as sinalizações de visibilidade do ambiente de execução com cuidado
Ao alternar a visibilidade do teclado de software no momento da execução, tome cuidado para não transmitir determinados
valores de sinalização nesses métodos. Por exemplo, se o aplicativo espera que o
teclado de software seja mostrado ao chamar
View.getWindowInsetsController().show(ime())
em Activity.onCreate()
durante
o início da atividade, os desenvolvedores precisam ter cuidado para não definir as flags
SOFT_INPUT_STATE_HIDDEN
ou SOFT_INPUT_STATE_ALWAYS_HIDDEN
durante a inicialização inicial caso o teclado de software esteja oculto inesperadamente.
O sistema geralmente oculta o teclado de software automaticamente
Na maioria das situações, o sistema oculta o teclado de software. Pode ser qualquer um dos seguintes casos:
- O usuário conclui a tarefa no campo de texto.
- O usuário pressiona a tecla "Voltar" ou faz gestos de deslizar com a navegação de retorno.
- O usuário navega para outro app, e esse outro app definiu as sinalizações
SOFT_INPUT_STATE_HIDDEN
ouSOFT_INPUT_STATE_ALWAYS_HIDDEN
quando a visualização ganha o foco.
Ocultar o teclado de software manualmente com base no comportamento anterior do sistema
Seu app precisa ocultar o teclado de software manualmente em algumas situações, por
exemplo, quando o campo de texto perde o foco em
View.OnFocusChangeListener.onFocusChange
. Use essa técnica com cuidado.
Fechar o teclado de software prejudica a experiência do usuário.
Se o app ocultar manualmente o teclado de software, você precisará saber se ele foi exibido explicitamente ou implicitamente:
Considera-se que o teclado de software foi mostrado explicitamente após uma chamada para
showSoftInput()
.Por outro lado, considera-se que o teclado de software tenha sido mostrado implicitamente em uma das seguintes condições:
- O sistema mostrou o teclado de software ao aplicar a
android:windowSoftInputMode
. - Seu app transmitiu
SHOW_IMPLICIT
parashowSoftInput()
.
- O sistema mostrou o teclado de software ao aplicar a
Normalmente, hideSoftInputFromWindow()
oculta o teclado de software, independente de
como foi solicitado, mas com HIDE_IMPLICIT_ONLY
ele pode se limitar a dispensar apenas um teclado de software solicitado implicitamente.
Mostrar uma caixa de diálogo ou visualização de sobreposição na parte superior do teclado de software
Em algumas situações, a atividade do editor pode precisar criar uma caixa de diálogo não editável ou uma janela de sobreposição sobre o teclado de software.
Seu app tem algumas opções, que são descritas nas seções a seguir.
Em resumo, processe corretamente as flags de janela do teclado de software direcionado à janela, de modo que ela atenda às seguintes expectativas em relação à ordem vertical (z-layer):
- Sem flags (com uso normal de maiúsculas e minúsculas): atrás da camada do teclado de software e pode receber texto.
FLAG_NOT_FOCUSABLE
: sobre a camada do teclado de software, mas não recebe texto.FLAG_ALT_FOCUSABLE_IM
: na parte superior da camada do teclado de software, ela pode estar em foco, mas não está conectada ao teclado de software. Também impede que todas as visualizações abaixo dele se conectem ao teclado de software. Isso é útil para mostrar uma caixa de diálogo do app que não usa entrada de texto acima da camada do teclado de software.FLAG_NOT_FOCUSABLE
eFLAG_ALT_FOCUSABLE_IM
: atrás da camada do teclado de software, mas não podem receber texto.FLAG_NOT_FOCUSABLE
eFLAG_NOT_TOUCH_MODAL
: na parte de cima do teclado de software, e permita que os eventos de toque passem pela janela para o teclado de software.
Criar uma caixa de diálogo
Use a sinalização da janela de diálogo
FLAG_ALT_FOCUSABLE_IM
para manter a caixa de diálogo na parte superior do teclado de software e
impedir que ele ganhe foco:
Kotlin
val content = TextView(this) content.text = "Non-editable dialog on top of soft keyboard" content.gravity = Gravity.CENTER val builder = AlertDialog.Builder(this) .setTitle("Soft keyboard layering demo") .setView(content) mDialog = builder.create() mDialog!!.window!! .addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM) mDialog!!.show()
Java
TextView content = new TextView(this); content.setText("Non-editable dialog on top of soft keyboard"); content.setGravity(Gravity.CENTER); final AlertDialog.Builder builder = new AlertDialog.Builder(this) .setTitle("Soft keyboard layering demo") .setView(content); mDialog = builder.create(); mDialog.getWindow().addFlags(FLAG_ALT_FOCUSABLE_IM); mDialog.show();
Criar uma visualização de sobreposição
Crie uma visualização de sobreposição especificando o tipo de janela
TYPE_APPLICATION_OVERLAY
e a flag de janela FLAG_ALT_FOCUSABLE_IM
pela atividade segmentada pelo teclado de software.
Kotlin
val params = WindowManager.LayoutParams( width, /* Overlay window width */ height, /* Overlay window height */ WindowManager.LayoutParams.TYPE_APPLICATION, /* Overlay window type */ WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM /* No need to allow for text input on top of the soft keyboard */ or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, /* Allow touch event send to soft keyboard behind the overlay */ PixelFormat.TRANSLUCENT ) params.title = "Overlay window" mOverlayView!!.layoutParams = params windowManager.addView(mOverlayView, params)
Java
WindowManager.LayoutParams params = new WindowManager.LayoutParams( width, /* Overlay window width */ height, /* Overlay window height */ TYPE_APPLICATION, /* Overlay window type */ FLAG_ALT_FOCUSABLE_IM /* No need to allow for text input on top of the soft keyboard */ | FLAG_NOT_TOUCH_MODAL, /* Allow touch event send to soft keyboard behind the overlay */ PixelFormat.TRANSLUCENT); params.setTitle("Overlay window"); mOverlayView.setLayoutParams(params); getWindowManager().addView(mOverlayView, params);
Mostrar uma caixa de diálogo ou visualização abaixo do teclado de software
Seu app pode precisar criar uma caixa de diálogo ou janela com as seguintes propriedades:
- Aparece abaixo do teclado de software solicitado por uma atividade do editor, de modo que não seja afetado pela entrada de texto.
- Permanece ciente das mudanças no tamanho do encarte do teclado de software para ajustar o layout da caixa de diálogo ou da janela.
Nesse caso, o app tem várias opções. As seções a seguir descrevem essas opções.
Criar uma caixa de diálogo
Crie uma caixa de diálogo configurando as sinalizações de janela FLAG_NOT_FOCUSABLE
e FLAG_ALT_FOCUSABLE_IM
:
Kotlin
val content = TextView(this) content.text = "Non-editable dialog behind soft keyboard" content.gravity = Gravity.CENTER val builder = AlertDialog.Builder(this) .setTitle("Soft keyboard layering demo") .setView(content) mDialog = builder.create() mDialog!!.window!! .addFlags(FLAG_NOT_FOCUSABLE or FLAG_ALT_FOCUSABLE_IM) mDialog!!.show()
Java
TextView content = new TextView(this); content.setText("Non-editable dialog behind soft keyboard"); content.setGravity(Gravity.CENTER); final AlertDialog.Builder builder = new AlertDialog.Builder(this) .setTitle("Soft keyboard layering demo") .setView(content); mDialog = builder.create(); mDialog.getWindow() .addFlags(FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM); mDialog.show();
Criar uma visualização de sobreposição
Crie uma visualização de sobreposição configurando as sinalizações de janela FLAG_NOT_FOCUSABLE
e FLAG_ALT_FOCUSABLE_IM
:
Kotlin
val params = WindowManager.LayoutParams( width, /* Overlay window width */ height, /* Overlay window height */ WindowManager.LayoutParams.TYPE_APPLICATION, /* Overlay window type */ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, PixelFormat.TRANSLUCENT ) params.title = "Overlay window" mOverlayView!!.layoutParams = params windowManager.addView(mOverlayView, params)
Java
WindowManager.LayoutParams params = new WindowManager.LayoutParams( width, /* Overlay window width */ height, /* Overlay window height */ TYPE_APPLICATION, /* Overlay window type */ FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM, PixelFormat.TRANSLUCENT); params.setTitle("Overlay window"); mOverlayView.setLayoutParams(params); getWindowManager().addView(mOverlayView, params);