Gerenciar a visibilidade do método de entrada

Quando o foco de entrada se move para dentro ou para fora de um campo de texto editável, o Android mostra ou oculta a entrada —por exemplo, o teclado na tela — apropriados. O sistema também decide como a interface e o campo de texto aparecem acima o 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, mas, talvez você queira mais controle sobre a visibilidade do método de entrada e como isso afeta o layout. Esta lição explica como controlar e responder a 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 atividade for iniciada, ele não mostrará o teclado de software. Esse comportamento é adequado porque a inserção de texto pode não ser a tarefa principal da atividade. No entanto, se inserir texto é de fato a tarefa principal, por exemplo, em uma tela de login, você precisará provavelmente quer que o teclado de software apareça por padrão.

Para mostrar o método de entrada quando sua atividade começar, adicione o android:windowSoftInputMode ao <activity> com o valor "stateVisible". 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íveis para a interface do seu app. O sistema decide como ajustar o valor da interface, mas pode não acertar. Para garantir o melhor comportamento para seu aplicativo, especifique como deseja que o sistema exiba sua interface no espaço restante.

Para declarar seu tratamento preferido em uma atividade, use o Atributo android:windowSoftInputMode no elemento <activity> do manifesto com uma das opções e a distribuição dos valores dos dados.

Por exemplo, para garantir que o sistema redimensione seu layout de acordo com os o que mantém todo o conteúdo do layout acessível, mesmo que requer rolagem. Use "adjustResize":

<application ... >
   <activity
       android:windowSoftInputMode="adjustResize" ... >
       ...
   </activity>
   ...
</application>

Você pode combinar a especificação de ajuste com o teclado de software inicial visibilidade da seção anterior:

<activity
    android:windowSoftInputMode="stateVisible|adjustResize" ... >
    ...
</activity>

É importante especificar "adjustResize" caso sua IU inclua controles que o o usuário pode precisar de acesso imediatamente após ou durante a entrada de texto. Para exemplo, se você usar um layout relativo para colocar uma barra de botões na parte inferior na tela, usando "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 atividade em que você queira garantir método de entrada estiver visível, será possível usar InputMethodManager para mostrá-lo.

Por exemplo, o método a seguir usa uma View em que o usuário deve digitar algo, chamar requestFocus() para conceder o foco e, em seguida, 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);
   }
}

Mostrar o teclado de software de forma confiável

Há certas situações, como quando uma atividade é iniciada, nas quais usando 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 a showSoftInput() depende nas seguintes condições:

  • A visualização já precisa estar conectada ao teclado de software. (Isso, por sua vez, Requer que a janela seja focada e o editor para solicitar o foco de visualização com View.requestFocus()).

  • A visibilidade também pode ser afetada pelo android:windowSoftInputMode e as flags usadas por showSoftInput().

Em certos casos de uso, como no início de uma atividade, alguns desses quando as condições obrigatórias não são atendidas. O sistema não considera a visualização como conectado 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, use o seguinte: alternativas:

Kotlin

editText.requestFocus()
WindowCompat.getInsetsController(window, editText)!!.show(WindowInsetsCompat.Type.ime())

Java

editText.requestFocus();
WindowCompat.getInsetsController(getWindow(), editText).show(WindowInsetsCompat.Type.ime());

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 flags de visibilidade do ambiente de execução com cuidado

Ao alternar a visibilidade do teclado de software durante a execução, tome cuidado para não passar certos sinalizar valores nesses métodos. Por exemplo, se o aplicativo espera o teclado de software é exibido ao chamar View.getWindowInsetsController().show(ime()) em Activity.onCreate() durante a atividade iniciar, os desenvolvedores do aplicativo deverão ter cuidado para não Sinalizações SOFT_INPUT_STATE_HIDDEN ou SOFT_INPUT_STATE_ALWAYS_HIDDEN durante a inicialização inicial caso o teclado de software fique oculto inesperadamente.

O sistema geralmente oculta o teclado de software automaticamente

Na maioria das situações, o sistema processa a ocultação do teclado de software. Isso 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 app definiu Sinalizações SOFT_INPUT_STATE_HIDDEN ou SOFT_INPUT_STATE_ALWAYS_HIDDEN quando a visualização recebe 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, como exemplo, quando o campo de texto perde o foco View.OnFocusChangeListener.onFocusChange Use essa técnica de forma criteriosa fechar o teclado de software prejudica inesperadamente a experiência do usuário.

Se o app ocultar manualmente o teclado de software, será necessário saber se o teclado de software foi mostrado de forma explícita ou implícita:

  • Considera-se que o teclado de software foi exibido explicitamente após fazer uma chamada para showSoftInput().

  • Por outro lado, considera-se que o teclado de software foi mostrado implicitamente em uma das seguintes condições:

    • O sistema mostrou o teclado de software enquanto aplicava o android:windowSoftInputMode:
    • Seu app transmitiu SHOW_IMPLICIT para showSoftInput()

Normalmente, o hideSoftInputFromWindow() oculta o teclado de software, independente da como foi solicitado, mas com HIDE_IMPLICIT_ONLY ele pode ser limitado a dispensar apenas um teclado de software solicitado implicitamente.

Mostrar uma caixa de diálogo ou visualização de sobreposição na parte de cima do teclado de software

Em algumas situações, a atividade do editor pode precisar criar um objeto não editável caixa de diálogo ou janela de sobreposição na parte superior do teclado de software.

Seu app tem algumas opções descritas nas seções a seguir.

Em resumo, certifique-se de processar corretamente as sinalizações de janela do teclado de software. segmentar a janela para que ela satisfaça as seguintes expectativas em relação à ordenação vertical (camada z):

  • Sem flags (caso normal): atrás da camada do teclado de software. Pode receber texto.
  • FLAG_NOT_FOCUSABLE : sobre a camada do teclado de software, mas não pode receber texto.
  • FLAG_ALT_FOCUSABLE_IM : na parte superior da camada do teclado de software, pode ser focado, mas não conectado ao usando o teclado virtual. Também impede que todas as visualizações abaixo dele se conectem ao usando o teclado virtual. Isso é útil para mostrar uma caixa de diálogo de app que não usa texto acima da camada do teclado de software.
  • FLAG_NOT_FOCUSABLE e FLAG_ALT_FOCUSABLE_IM : atrás da camada do teclado de software, mas não recebe texto.
  • FLAG_NOT_FOCUSABLE e FLAG_NOT_TOUCH_MODAL : na parte superior do teclado de software, permitir que os eventos de toque passem "through" da janela no teclado de software.

Criar uma caixa de diálogo

Usar o FLAG_ALT_FOCUSABLE_IM sinalização da janela de diálogo para mantê-la na parte superior do teclado de software e para impedir que o teclado de software 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

Criar uma visualização de sobreposição especificando TYPE_APPLICATION_OVERLAY tipo de janela e FLAG_ALT_FOCUSABLE_IM pela atividade segmentada do 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 o propriedades a seguir:

  • Aparece abaixo do teclado de software solicitado por uma atividade do editor para que não seja afetado pela entrada de texto.
  • Permanece ciente das mudanças no tamanho do encarte do teclado de software em 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 descrever essas opções.

Criar uma caixa de diálogo

Criar uma caixa de diálogo configurando os FLAG_NOT_FOCUSABLE flag de janela e FLAG_ALT_FOCUSABLE_IM flag de janela:

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

Criar uma visualização de sobreposição definindo as FLAG_NOT_FOCUSABLE flag de janela e FLAG_ALT_FOCUSABLE_IM flag de janela:

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