Un editor del metodo di input (IME) è un controllo utente che consente agli utenti di inserire testo. Android fornisce un framework del metodo di input estensibile che consente alle applicazioni di fornire agli utenti metodi di input alternativi, come tastiere sullo schermo o input vocale. Dopo aver installato gli IME, l'utente può selezionarne uno dalle impostazioni di sistema e utilizzarlo in tutto il sistema. È possibile attivare un solo IME alla volta.
Per aggiungere un IME al sistema Android, crea un'app per Android contenente una classe che estende InputMethodService.
Inoltre, in genere crei un'attività "Impostazioni" che passa le opzioni al servizio IME. Puoi anche definire una UI delle impostazioni che viene visualizzata come parte delle impostazioni di sistema.
Questa pagina tratta i seguenti argomenti:
- Il ciclo di vita dell'IME
- Dichiarazione dei componenti IME nel file manifest dell'applicazione
- L'API IME
- Progettazione di una UI IME
- Invio di testo da un IME a un'applicazione
- Utilizzo dei sottotipi IME
- Altre considerazioni sull'IME
Se non hai mai utilizzato gli IME, leggi prima l'articolo introduttivo Metodi di input sullo schermo.
Il ciclo di vita dell'IME
Il seguente diagramma descrive il ciclo di vita di un IME:
Le sezioni seguenti descrivono come implementare la UI e il codice associati a un IME che segue questo ciclo di vita.
Dichiarare i componenti IME nel file manifest
Nel sistema Android, un IME è un'app per Android che contiene un servizio IME speciale. Il file manifest dell'applicazione deve dichiarare il servizio, richiedere le autorizzazioni necessarie, fornire un filtro per intent che corrisponda all'azione action.view.InputMethod e fornire metadati che definiscono le caratteristiche dell'IME. Inoltre, per fornire un'interfaccia delle impostazioni che consenta all'utente di modificare il comportamento dell'IME, puoi definire un'attività "Impostazioni" che può essere avviata dalle Impostazioni di sistema.
Il seguente snippet dichiara un servizio IME. Richiede l'autorizzazione BIND_INPUT_METHOD per consentire al servizio di connettere l'IME al sistema, configura un filtro per intent che corrisponda all'azione android.view.InputMethod e definisce i metadati per l'IME:
<!-- Declares the input method service. --> <service android:name="FastInputIME" android:label="@string/fast_input_label" android:permission="android.permission.BIND_INPUT_METHOD"> <intent-filter> <action android:name="android.view.InputMethod" /> </intent-filter> <meta-data android:name="android.view.im" android:resource="@xml/method" /> </service>
Il seguente snippet dichiara l'attività delle impostazioni per l'IME. Ha un filtro per intent per ACTION_MAIN che indica che questa attività è il punto di ingresso principale per l'applicazione IME:
<!-- Optional: an activity for controlling the IME settings. --> <activity android:name="FastInputIMESettings" android:label="@string/fast_input_settings"> <intent-filter> <action android:name="android.intent.action.MAIN"/> </intent-filter> </activity>
Puoi anche fornire l'accesso alle impostazioni dell'IME direttamente dalla relativa UI.
L'API del metodo di input
Le classi specifiche per gli IME si trovano nei pacchetti android.inputmethodservice e android.view.inputmethod. La classe KeyEvent è importante per la gestione dei caratteri della tastiera.
La parte centrale di un IME è un componente di servizio, ovvero una classe che estende InputMethodService. Oltre a implementare il normale ciclo di vita del servizio, questa classe ha callback per fornire la UI dell'IME, gestire l'input utente e fornire testo al campo che ha lo stato attivo. Per impostazione predefinita, la classe InputMethodService fornisce la maggior parte dell'implementazione per la gestione dello stato e della visibilità dell'IME e per la comunicazione con il campo di immissione corrente.
Anche le seguenti classi sono importanti:
BaseInputConnection-
Definisce il canale di comunicazione da un
InputMethodall'applicazione che riceve il suo input. Lo utilizzi per leggere il testo intorno al cursore, inserire testo nella casella di testo e inviare eventi di tasti non elaborati all'applicazione. Le applicazioni devono estendere questa classe anziché implementare l'interfaccia di baseInputConnection. KeyboardView-
Un'estensione di
Viewche esegue il rendering di una tastiera e risponde agli eventi di input utente. Il layout della tastiera è specificato da un 'istanza diKeyboard, che puoi definire in un file XML.
Progettare la UI del metodo di input
Esistono due elementi visivi principali per un IME: la visualizzazione input e la visualizzazione candidati. Devi implementare solo gli elementi pertinenti al metodo di input che stai progettando.
Visualizzazione input
La visualizzazione input è la UI in cui l'utente inserisce testo sotto forma di clic sui tasti, scrittura a mano o gesti. Quando l'IME viene visualizzato per la prima volta, il sistema chiama il callback onCreateInputView(). Nell'implementazione di questo metodo, crea il layout che vuoi visualizzare nella finestra IME e restituiscilo al sistema. Il seguente snippet mostra un esempio di implementazione del metodo onCreateInputView():
Kotlin
override fun onCreateInputView(): View { return layoutInflater.inflate(R.layout.input, null).apply { if (this is MyKeyboardView) { setOnKeyboardActionListener(this@MyInputMethod) keyboard = latinKeyboard } } }
Java
@Override public View onCreateInputView() { MyKeyboardView inputView = (MyKeyboardView) getLayoutInflater().inflate(R.layout.input, null); inputView.setOnKeyboardActionListener(this); inputView.setKeyboard(latinKeyboard); return inputView; }
In questo esempio, MyKeyboardView è un'istanza di un'implementazione personalizzata di
KeyboardView che esegue il rendering di un Keyboard.
Visualizzazione candidati
La visualizzazione candidati è la UI in cui l'IME mostra le potenziali correzioni di parole o i suggerimenti che l'utente può selezionare. Nel ciclo di vita dell'IME, il sistema chiama onCreateCandidatesView() quando è pronto per visualizzare la visualizzazione candidati. Nell'implementazione di questo metodo, restituisci un layout che mostra i suggerimenti di parole oppure restituisci null se non vuoi mostrare nulla. Una risposta null è il comportamento predefinito, quindi non devi implementare questa funzionalità se non fornisci suggerimenti.
Considerazioni sulla progettazione della UI
Questa sezione descrive alcune considerazioni sulla progettazione della UI per gli IME.
Gestire più dimensioni dello schermo
La UI del tuo IME deve essere in grado di scalare per diverse dimensioni dello schermo e gestire sia l'orientamento orizzontale sia quello verticale. Nella modalità IME non a schermo intero, lascia spazio sufficiente all'applicazione per mostrare il campo di testo e qualsiasi contesto associato, in modo che non più della metà dello schermo sia occupata dall'IME. Nella modalità IME a schermo intero, questo non è un problema.
Gestire diversi tipi di input
I campi di testo di Android consentono di impostare un tipo di input specifico, ad esempio testo in formato libero, numeri, URL, indirizzi email e stringhe di ricerca. Quando implementi un nuovo IME, rileva il tipo di input di ogni campo e fornisci l'interfaccia appropriata. Tuttavia, non devi configurare l'IME per verificare se l'utente inserisce testo valido per il tipo di input. Questa è responsabilità dell'applicazione proprietaria del campo di testo.
Ad esempio, ecco l'interfaccia fornita dall'IME per le lingue latine per l'input di testo della piattaforma Android:
Ed ecco l'interfaccia fornita dall'IME per le lingue latine per l'input numerico della piattaforma Android:
Quando un campo di immissione riceve lo stato attivo e l'IME viene avviato, il sistema chiama onStartInputView(), passando un oggetto EditorInfo che contiene dettagli sul tipo di input e altri attributi del campo di testo. In questo oggetto, il campo inputType contiene il tipo di input del campo di testo.
Il campo inputType è un int che contiene pattern di bit per varie impostazioni del tipo di input. Per testarlo per il tipo di input del campo di testo, mascheralo con la costante TYPE_MASK_CLASS, come segue:
Kotlin
inputType and InputType.TYPE_MASK_CLASS
Java
inputType & InputType.TYPE_MASK_CLASS
Il pattern di bit del tipo di input può avere uno dei seguenti valori:
TYPE_CLASS_NUMBER- Un campo di testo per l'inserimento di numeri. Come illustrato nella Figura 3, l'IME per le lingue latine mostra un tastierino numerico per i campi di questo tipo.
TYPE_CLASS_DATETIME- Un campo di testo per l'inserimento di una data e un'ora.
TYPE_CLASS_PHONE- Un campo di testo per l'inserimento di numeri di telefono.
TYPE_CLASS_TEXT- Un campo di testo per l'inserimento di tutti i caratteri supportati.
Queste costanti sono descritte in maggiore dettaglio nella documentazione di riferimento per InputType.
Il campo inputType può contenere altri bit che indicano una variante del tipo di campo di testo, ad esempio:
TYPE_TEXT_VARIATION_PASSWORD- Una variante di
TYPE_CLASS_TEXTper l'inserimento di password. Il metodo di input mostra simboli anziché il testo effettivo. TYPE_TEXT_VARIATION_URI- Una variante di
TYPE_CLASS_TEXTper l'inserimento di URL web e altri Uniform Resource Identifiers (URI). TYPE_TEXT_FLAG_AUTO_COMPLETE- Una variante di
TYPE_CLASS_TEXTper l'inserimento di testo che l'applicazione completa automaticamente da un dizionario, una ricerca o un'altra funzionalità.
Quando testi queste varianti, maschera inputType con la costante appropriata. Le costanti di maschera disponibili sono elencate nella documentazione di riferimento per InputType.
Inviare testo all'applicazione
Man mano che l'utente inserisce testo con l'IME, puoi inviarlo all'applicazione inviando singoli eventi di tasti o modificando il testo intorno al cursore nel campo di testo dell'applicazione. In entrambi i casi, utilizza un'istanza di InputConnection per fornire il testo. Per ottenere questa istanza, chiama InputMethodService.getCurrentInputConnection().
Modificare il testo intorno al cursore
Quando gestisci la modifica del testo esistente, alcuni metodi utili in BaseInputConnection sono i seguenti:
-
getTextBeforeCursor() - Restituisce un
CharSequencecontenente il numero di caratteri richiesti prima della posizione corrente del cursore. -
getTextAfterCursor() - Restituisce un
CharSequencecontenente il numero di caratteri richiesti dopo la posizione corrente del cursore. -
deleteSurroundingText() - Elimina il numero specificato di caratteri prima e dopo la posizione corrente del cursore.
-
commitText() - Inserisce un
CharSequencenel campo di testo e imposta una nuova posizione del cursore.
Ad esempio, il seguente snippet mostra come sostituire i quattro caratteri a sinistra del cursore con il testo "Hello!":
Kotlin
currentInputConnection.also { ic: InputConnection -> ic.deleteSurroundingText(4, 0) ic.commitText("Hello", 1) ic.commitText("!", 1) }
Java
InputConnection ic = getCurrentInputConnection(); ic.deleteSurroundingText(4, 0); ic.commitText("Hello", 1); ic.commitText("!", 1);
Supportare la composizione del testo prima dell'inserimento
Se l'IME prevede il testo o richiede più passaggi per comporre un glifo o una parola, puoi mostrare l'avanzamento nel campo di testo finché l'utente non inserisce la parola, quindi puoi sostituire la composizione parziale con il testo completato. Puoi dare un trattamento speciale al testo aggiungendo uno span quando lo passi a setComposingText().
Il seguente snippet mostra come visualizzare l'avanzamento in un campo di testo:
Kotlin
currentInputConnection.also { ic: InputConnection -> ic.setComposingText("Composi", 1) ic.setComposingText("Composin", 1) ic.commitText("Composing ", 1) }
Java
InputConnection ic = getCurrentInputConnection(); ic.setComposingText("Composi", 1); ic.setComposingText("Composin", 1); ic.commitText("Composing ", 1);
Intercettare gli eventi dei tasti hardware
Anche se la finestra del metodo di immissione non ha lo stato attivo esplicito, riceve prima gli eventi dei tasti hardware e può utilizzarli o inoltrarli all'applicazione. Ad esempio, potresti voler utilizzare i tasti direzionali per navigare all'interno della UI per la selezione dei candidati durante la composizione. Potresti anche voler intercettare il tasto Indietro per chiudere tutte le finestre di dialogo provenienti dalla finestra del metodo di input.
Per intercettare i tasti hardware, esegui l'override di onKeyDown() e onKeyUp().
Chiama il metodo super() per i tasti che non vuoi gestire personalmente.
Creare un sottotipo IME
I sottotipi consentono all'IME di esporre più modalità di input e lingue supportate da un IME. Un sottotipo può rappresentare quanto segue:
- Un'impostazione internazionale, ad esempio en_US o fr_FR
- Una modalità di input, ad esempio vocale, tastiera o scrittura a mano
- Altri stili, moduli o proprietà di input specifici per l'IME, ad esempio layout di tastiera a 10 tasti o QWERTY
La modalità può essere qualsiasi testo, ad esempio "tastiera" o "vocale". Un sottotipo può anche esporre una combinazione di questi elementi.
Le informazioni sui sottotipi vengono utilizzate per una finestra di dialogo di cambio IME disponibile dalla barra delle notifiche e per le impostazioni IME. Le informazioni consentono inoltre al framework di visualizzare direttamente un sottotipo specifico di un IME. Quando crei un IME, utilizza la funzionalità dei sottotipi, perché aiuta l'utente a identificare e passare da una lingua e una modalità IME all'altra.
Definisci i sottotipi in uno dei file di risorse XML del metodo di input utilizzando l'elemento
<subtype>. Il seguente snippet di codice definisce un IME con due sottotipi: un sottotipo di tastiera per le impostazioni internazionali inglese statunitense e un altro sottotipo di tastiera per le impostazioni internazionali della lingua francese per la Francia:
<input-method xmlns:android="http://schemas.android.com/apk/res/android" android:settingsActivity="com.example.softkeyboard.Settings" android:icon="@drawable/ime_icon"> <subtype android:name="@string/display_name_english_keyboard_ime" android:icon="@drawable/subtype_icon_english_keyboard_ime" android:languageTag="en-US" android:imeSubtypeMode="keyboard" android:imeSubtypeExtraValue="somePrivateOption=true" /> <subtype android:name="@string/display_name_french_keyboard_ime" android:icon="@drawable/subtype_icon_french_keyboard_ime" android:languageTag="fr-FR" android:imeSubtypeMode="keyboard" android:imeSubtypeExtraValue="someVariable=30,someInternalOption=false" /> <subtype android:name="@string/display_name_german_keyboard_ime" ... /> </input-method>
Per assicurarti che i sottotipi siano etichettati correttamente nella UI, utilizza `%s` per ottenere un'etichetta di sottotipo che sia uguale all'etichetta delle impostazioni internazionali del sottotipo. Questo è illustrato nei due snippet di codice successivi. Il primo snippet mostra una parte del file XML del metodo di input:
<subtype android:label="@string/label_subtype_generic" android:imeSubtypeLocale="en_US" android:icon="@drawable/icon_en_us" android:imeSubtypeMode="keyboard" />
Il seguente snippet fa parte del file strings.xml dell'IME. La risorsa stringa label_subtype_generic, utilizzata dalla definizione della UI del metodo di input per impostare l'etichetta del sottotipo, è definita come segue:
<string name="label_subtype_generic">%s</string>Questa impostazione fa sì che il nome visualizzato del sottotipo corrisponda all'impostazione delle impostazioni internazionali. Ad esempio, in qualsiasi impostazione internazionale inglese, il nome visualizzato è "Inglese (Stati Uniti)".
Scegliere i sottotipi IME dalla barra delle notifiche
Il sistema Android gestisce tutti i sottotipi esposti da tutti gli IME. I sottotipi IME vengono trattati come modalità dell'IME a cui appartengono. L'utente può passare dalla barra delle notifiche o dall'app Impostazioni a un menu di sottotipi IME disponibili, come mostrato nella figura seguente:
Scegliere i sottotipi IME dalle Impostazioni di sistema
L'utente può anche controllare come vengono utilizzati i sottotipi nel riquadro delle impostazioni Lingua e input nelle impostazioni di sistema:
Passare da un sottotipo IME all'altro
Puoi consentire agli utenti di passare facilmente da un sottotipo IME all'altro fornendo un tasto di cambio, ad esempio l'icona della lingua a forma di globo sulla tastiera. In questo modo, la tastiera è più facile da usare ed è comoda per l'utente. Per attivare questo cambio, segui questi passaggi:
- Dichiara
supportsSwitchingToNextInputMethod = "true"nei file di risorse XML del metodo di input. La dichiarazione deve essere simile al seguente snippet di codice:<input-method xmlns:android="http://schemas.android.com/apk/res/android" android:settingsActivity="com.example.softkeyboard.Settings" android:icon="@drawable/ime_icon" android:supportsSwitchingToNextInputMethod="true">
- Chiama il
shouldOfferSwitchingToNextInputMethod()metodo. - Se il metodo restituisce true, mostra un tasto di cambio.
- Quando l'utente tocca il tasto di cambio, chiama
switchToNextInputMethod(), passando false. Un valore false indica al sistema di trattare tutti i sottotipi allo stesso modo, indipendentemente da a quale IME appartengono. Se specifichi true, il sistema scorre i sottotipi nell' IME corrente.
Considerazioni generali sull'IME
Ecco altri aspetti da considerare durante l'implementazione dell'IME:
- Fornisci un modo per consentire agli utenti di impostare le opzioni direttamente dalla UI dell'IME.
- Fornisci un modo per consentire agli utenti di passare a un altro IME direttamente dalla UI del metodo di input, perché sul dispositivo potrebbero essere installati più IME.
- Visualizza rapidamente la UI dell'IME. Precarica o carica su richiesta tutte le risorse di grandi dimensioni in modo che gli utenti vedano l'IME non appena toccano un campo di testo. Memorizza nella cache le risorse e le visualizzazioni per le successive chiamate del metodo di input.
- Rilascia immediatamente le allocazioni di memoria di grandi dimensioni dopo che la finestra del metodo di input è nascosta, in modo che le applicazioni abbiano memoria sufficiente per essere eseguite. Utilizza un messaggio ritardato per rilasciare le risorse se l'IME è nascosto per alcuni secondi.
- Assicurati che gli utenti possano inserire il maggior numero possibile di caratteri per la lingua o le impostazioni internazionali associate all'IME. Gli utenti potrebbero utilizzare la punteggiatura nelle password o nei nomi utente, quindi l'IME deve fornire molti caratteri diversi per consentire agli utenti di inserire una password e accedere al dispositivo.