Consente di gestire la visibilità del metodo di immissione.

Quando lo stato attivo dell'input viene spostato all'interno o all'esterno di un campo di testo modificabile, Android mostra o nasconde l'input, ad esempio la tastiera sullo schermo, a seconda dei casi. Il sistema decide anche in che modo visualizzare l'interfaccia utente e il campo di testo sopra il metodo di immissione. Ad esempio, quando lo spazio verticale sullo schermo è limitato, il campo di testo potrebbe occupare tutto lo spazio sopra il metodo di immissione.

Per la maggior parte delle app, questi comportamenti predefiniti sono sufficienti. Tuttavia, in alcuni casi è preferibile avere un maggiore controllo sulla visibilità del metodo di inserimento e su come questo influisce sul layout. Questa lezione spiega come controllare e rispondere alla visibilità del metodo di input.

Mostra la tastiera soft quando inizia l'attività

Anche se Android dà lo stato attivo al primo campo di testo nel layout all'avvio dell'attività, non mostra la tastiera software. Questo comportamento è appropriato perché l'inserimento di testo potrebbe non essere l'attività principale dell'attività. Tuttavia, se l'inserimento di testo è davvero l'attività principale, ad esempio in una schermata di accesso, è probabile che la tastiera virtuale venga visualizzata per impostazione predefinita.

Per mostrare il metodo di immissione all'inizio dell'attività, aggiungi l'attributo android:windowSoftInputMode all'elemento <activity> con il valore "stateVisible". Ecco alcuni esempi:

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

Specifica come deve rispondere la tua UI

Quando la tastiera software viene visualizzata sullo schermo, riduce la quantità di spazio disponibile per l'interfaccia utente dell'app. Il sistema decide come modificare la porzione visibile dell'interfaccia utente, ma potrebbe non riuscirci. Per garantire il comportamento migliore per la tua app, specifica la modalità di visualizzazione della tua UI da parte del sistema nello spazio rimanente.

Per dichiarare il trattamento preferito in un'attività, utilizza l'attributo android:windowSoftInputMode nell'elemento <activity> del tuo manifest con uno dei valori "adjust".

Ad esempio, per assicurarti che il sistema ridimensioni il layout in base allo spazio disponibile, in modo da mantenere accessibili tutti i contenuti del layout, anche se è necessario scorrere, utilizza "adjustResize":

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

Puoi combinare la specifica di regolazione con la specifica di visibilità della tastiera virtuale iniziale della sezione precedente:

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

La specifica di "adjustResize" è importante se la UI include controlli a cui l'utente potrebbe dover accedere immediatamente dopo o durante l'inserimento di testo. Ad esempio, se utilizzi un layout relativo per posizionare la barra dei pulsanti nella parte inferiore dello schermo, l'utilizzo di "adjustResize" ridimensiona il layout in modo che la barra dei pulsanti appaia sopra la tastiera software.

Mostra la tastiera software on demand

Se nel ciclo di vita dell'attività vuoi assicurarti che il metodo di input sia visibile, puoi utilizzare InputMethodManager per mostrarlo.

Ad esempio, il seguente metodo prende un elemento View in cui l'utente deve digitare qualcosa. Chiama requestFocus() per impostare lo stato attivo, quindi chiama showSoftInput() per aprire il metodo di immissione:

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

Mostra la tastiera morbida in modo affidabile

In alcuni casi, ad esempio quando inizia un'attività, l'utilizzo di InputMethodManager.showSoftInput() per visualizzare la tastiera software potrebbe rendere la tastiera software non visibile all'utente.

La visibilità della tastiera software durante l'utilizzo di showSoftInput() dipende dalle seguenti condizioni:

  • La vista deve essere già collegata alla tastiera software. (Ciò, a sua volta, richiede che la finestra sia attiva e che la vista editor richieda lo stato attivo della visualizzazione con View.requestFocus()).

  • La visibilità può essere influenzata anche dall'attributo android:windowSoftInputMode e dai flag utilizzati da showSoftInput().

In alcuni casi d'uso, ad esempio all'avvio di un'attività, alcune di queste condizioni obbligatorie non sono soddisfatte. Il sistema non considera la vista come collegata alla tastiera software, ignora la chiamata showSoftInput() e la tastiera software non è visibile all'utente.

Per assicurarti che la tastiera software venga visualizzata in modo affidabile, puoi utilizzare le seguenti alternative:

  • (Consigliato) Utilizzo WindowInsetsControllerCompat. Questo oggetto mostra la tastiera software durante il comando Activity.onCreate(), come mostrato nello snippet di codice riportato di seguito. Garantisce che la chiamata venga pianificata dopo lo stato attivo della finestra.

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

Gestisci attentamente i flag di visibilità del runtime

Quando attivi/disattivi la visibilità della tastiera software in fase di runtime, fai attenzione a non trasferire determinati valori di flag a questi metodi. Ad esempio, se l'applicazione prevede che venga visualizzata la tastiera software quando chiami View.getWindowInsetsController().show(ime()) in Activity.onCreate() durante l'avvio dell'attività, gli sviluppatori dell'applicazione devono fare attenzione a non impostare i flag SOFT_INPUT_STATE_HIDDEN o SOFT_INPUT_STATE_ALWAYS_HIDDEN durante l'avvio iniziale, nel caso in cui la tastiera virtuale venga nascosta in modo imprevisto.

In genere il sistema nasconde automaticamente la tastiera software

Nella maggior parte dei casi, il sistema gestisce la modalità di occultamento della tastiera software. Può trattarsi di uno dei seguenti casi:

  • L'utente completa l'attività nel campo di testo.
  • L'utente preme il tasto Indietro o i gesti di scorrimento con la navigazione indietro.
  • L'utente passa a un'altra app e quest'ultima ha impostato i flag SOFT_INPUT_STATE_HIDDEN o SOFT_INPUT_STATE_ALWAYS_HIDDEN quando la visualizzazione viene messa in evidenza.

Nascondi manualmente la tastiera software in base al comportamento precedente del sistema

L'app deve nascondere manualmente la tastiera software in alcune situazioni, ad esempio quando il campo di testo perde lo stato attivo in View.OnFocusChangeListener.onFocusChange. Utilizza questa tecnica con prudenza; la chiusura della tastiera morbida compromette inaspettatamente l'esperienza utente.

Se la tua app nasconde manualmente la tastiera software, devi sapere se questa è stata mostrata in modo esplicito o implicitamente:

  • La tastiera software è considerata come mostrata esplicitamente dopo una chiamata a showSoftInput().

  • Al contrario, si considera che la tastiera software sia stata mostrata implicitamente in una delle seguenti condizioni:

    • Il sistema ha mostrato la tastiera software durante l'applicazione di android:windowSoftInputMode.
    • L'app è passata a SHOW_IMPLICIT a showSoftInput().

Normalmente, hideSoftInputFromWindow() nasconde la tastiera software indipendentemente da come è stata richiesta, ma con HIDE_IMPLICIT_ONLY può essere limitata alla sola chiusura di una tastiera software richiesta implicitamente.

Mostra una visualizzazione overlay o di una finestra di dialogo sopra la tastiera software

In alcuni casi, per l'attività dell'editor potrebbe essere necessario creare una finestra di dialogo non modificabile o una finestra overlay sopra la tastiera software.

La tua app ha alcune opzioni descritte nelle sezioni seguenti.

In sintesi, assicurati di gestire correttamente i flag della finestra della tastiera software che hanno come target la finestra in modo che soddisfi le seguenti aspettative in merito all'ordine verticale (z-layer):

  • Nessun flag (uso normale di lettere maiuscole e minuscole): dietro il livello della tastiera flessibile; puoi ricevere testo.
  • FLAG_NOT_FOCUSABLE : in cima al livello della tastiera flessibile, ma non consente di ricevere testo.
  • FLAG_ALT_FOCUSABLE_IM : sul livello della tastiera software è possibile impostare lo stato attivo sul livello superiore della tastiera software, ma non è collegato alla tastiera virtuale. Impedisce inoltre la connessione di tutte le viste sotto il tablet alla tastiera virtuale. È utile per mostrare una finestra di dialogo dell'app che non utilizza l'input di testo sopra il livello della tastiera software.
  • FLAG_NOT_FOCUSABLE e FLAG_ALT_FOCUSABLE_IM : si trova dietro il livello della tastiera flessibile, ma non consente di ricevere testo.
  • FLAG_NOT_FOCUSABLE e FLAG_NOT_TOUCH_MODAL : sopra la tastiera software, consenti agli eventi tocco di "attraversare" la finestra sulla tastiera.

Crea una finestra di dialogo

Utilizza il flag della finestra di dialogo FLAG_ALT_FOCUSABLE_IM per mantenere la finestra di dialogo in cima alla tastiera software ed evitare che quest'ultima diventi lo stato attivo:

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

Creare una visualizzazione overlay

Crea una visualizzazione overlay specificando il tipo di finestra TYPE_APPLICATION_OVERLAY e il flag della finestra FLAG_ALT_FOCUSABLE_IM in base all'attività della tastiera software scelta come target.

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

Mostra una finestra di dialogo o una visualizzazione sotto la tastiera software

L'app potrebbe dover creare una finestra di dialogo con le seguenti proprietà:

  • Viene visualizzato sotto la tastiera software richiesta dall'attività dell'editor, in modo che non sia influenzata dall'inserimento di testo.
  • È consapevole delle modifiche apportate alle dimensioni dei riquadri della tastiera virtuale per regolare il layout della finestra o della finestra di dialogo.

In questo caso, la tua app ha diverse opzioni. Queste opzioni sono descritte nelle sezioni seguenti.

Crea una finestra di dialogo

Crea una finestra di dialogo impostando sia il flag finestra FLAG_NOT_FOCUSABLE sia il flag finestra 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();

Creare una visualizzazione overlay

Per creare una visualizzazione overlay, imposta sia il flag della finestra FLAG_NOT_FOCUSABLE sia il flag della finestra 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);