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 dashowSoftInput()
.
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 comandoActivity.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());
- Pubblica un elemento eseguibile. In questo modo l'app attende fino a quando non riceve l'evento di stato attivo della finestra da
View.onWindowFocusChanged()
prima di chiamareshowSoftInput()
.
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
oSOFT_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
ashowSoftInput()
.
- Il sistema ha mostrato la tastiera software durante l'applicazione di
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
eFLAG_ALT_FOCUSABLE_IM
: si trova dietro il livello della tastiera flessibile, ma non consente di ricevere testo.FLAG_NOT_FOCUSABLE
eFLAG_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);