Editor di testo personalizzati

Gli editor di testo personalizzati sono viste che non sono componenti EditText o widget di testo WebView, ma supportano comunque l'inserimento di testo implementando il callback onCreateInputConnection(), che viene chiamato quando una vista è attiva e il sistema richiede un InputConnection per la vista.

Una chiamata a onCheckIsTextEditor() da un editor di testo personalizzato dovrebbe restituire true.

Supporto della scrittura a mano libera con stilo negli editor di testo personalizzati

Android 14 (livello API 34) e versioni successive supportano l'inserimento dello stilo nei componenti di immissione di testo standard di Android per impostazione predefinita (consulta la sezione Inserimento stilo nei campi di testo). Tuttavia, i campi di immissione di testo personalizzati (o editor) richiedono uno sviluppo aggiuntivo.

Per creare un editor di testo personalizzato:

  1. Attiva avvio della scrittura a mano libera
  2. Dichiara il supporto della scrittura a mano libera
  3. Supporta i gesti di scrittura a mano libera (seleziona, elimina, inserisci e così via)
  4. Fornisci all'IME la posizione del cursore e altri dati sulla posizione
  5. Mostra l'icona del passaggio del mouse per la scrittura a mano libera con stilo

Attiva avvio della scrittura a mano libera

Se una vista è costituita esclusivamente da un unico editor di testo, il sistema di visualizzazione può avviare automaticamente la scrittura a mano libera con lo stilo per la vista. In caso contrario, la vista deve implementare la propria logica di avvio della scrittura a mano libera.

Avvio automatico della scrittura a mano libera

Se una vista mostra un solo editor di testo e nessun altro contenuto, può attivare l'avvio automatico della scrittura a mano libera del sistema di visualizzazione chiamando setAutoHandwritingEnabled(true).

Quando la scrittura a mano libera automatica è attivata, il movimento con lo stilo che inizia in qualsiasi punto entro i limiti della scrittura a mano libera della visualizzazione attiva automaticamente la modalità di scrittura a mano libera. L'editor del metodo di input (IME) riceve gli eventi di movimento dello stilo e esegue il commit del testo riconosciuto.

Campo di immissione con un rettangolo circostante che indica i limiti per il rilevamento di eventi di movimento dello stilo.
Figura 1. Scrittura a mano libera entro i limiti di un campo EditText.

Avvio personalizzato della scrittura a mano libera

Se una visualizzazione include più editor di testo o contenuti oltre a un singolo editor di testo, deve implementare la propria logica di avvio della scrittura a mano libera come segue:

  1. Disattiva l'avvio automatico della scrittura a mano libera del sistema di visualizzazione chiamando setAutoHandwritingEnabled(false).

  2. Tieni traccia di tutti gli editor di testo visibili all'interno della visualizzazione.

  3. Monitora gli eventi di movimento ricevuti dalla visualizzazione in dispatchTouchEvent().

    • Quando il movimento dello stilo si verifica entro i limiti di scrittura a mano libera di un editor di testo, attiva l'editor di testo (se non lo è già).

    • Se lo stato attivo dell'editor non era già impostato, riavvia l'IME dell'editor con nuovi contenuti chiamando InputMethodManager#restartInput().

    • Avvia la sessione di scrittura a mano libera con lo stilo chiamando InputMethodManager#startStylusHandwriting().

Se un editor di testo si trova all'interno di una visualizzazione scorrevole, il movimento dello stilo entro i limiti di scrittura a mano libera dell'editor deve essere considerato scrittura a mano libera, non scorrimento. Utilizza ViewParent#requestDisallowInterceptTouchEvent() per impedire a una visualizzazione dei predecessori scorrevole di intercettare eventi tocco da un editor di testo.

Dettagli API

  • MotionEvent#getToolType() — Indica se MotionEvent proviene da uno stilo, nel qual caso il valore restituito è TOOL_TYPE_STYLUS o TOOL_TYPE_ERASER.

  • InputMethodManager#isStylusHandwritingAvailable() : indica se l'IME supporta la scrittura a mano libera con lo stilo. Chiama questo metodo prima di ogni chiamata a InputMethodManager#startStylusHandwriting() poiché la disponibilità della scrittura a mano libera potrebbe essere cambiata.

  • InputMethodManager#startStylusHandwriting() : fa entrare l'IME in modalità di scrittura a mano libera. Un evento di movimento ACTION_CANCEL viene inviato all'app per annullare il gesto corrente. Gli eventi di movimento dello stilo non vengono più inviati all'app.

    Gli eventi di movimento dello stilo del gesto corrente che sono già stati inviati all'app vengono inoltrati all'IME. L'IME è necessario per mostrare una finestra di inchiostro stilo attraverso la quale l'IME riceve tutti i seguenti oggetti MotionEvent. L'IME esegue il commit del testo scritto a mano libera utilizzando le API InputConnection.

    Se l'IME non riesce ad attivare la modalità di scrittura a mano libera, questa chiamata di metodo è automatica.

Dichiara il supporto della scrittura a mano libera

Durante la compilazione dell'argomento EditorInfo della chiamata View#onCreateInputConnection(EditorInfo) setStylusHandwritingEnabled() per comunicare all'IME che l'editor di testo supporta la scrittura a mano libera. Dichiara i gesti supportati con setSupportedHandwritingGestures() e setSupportedHandwritingGesturePreviews().

Supporta i gesti di scrittura a mano libera

Gli IME supportano vari gesti di scrittura a mano libera, come cerchiare il testo per selezionarlo o scarabocchiarci sopra il testo per eliminarlo.

Figura 2. Cerchia per selezionare il testo.
Figura 3. Scarabocchia per eliminare testo.

Gli editor personalizzati implementano InputConnection#performHandwritingGesture() e InputConnection#previewHandwritingGesture() per supportare diversi HandwritingGesture tipi, come SelectGesture, DeleteGesture e InsertGesture.

Dichiara i gesti di scrittura a mano libera supportati quando compili l'argomento EditorInfo di View#onCreateInputConnection(EditorInfo) (consulta la sezione Dichiara il supporto della scrittura a mano libera).

Dettagli API

  • InputConnection#performHandwritingGesture(HandwritingGesture, Executor, IntConsumer) : implementa i gesti. L'argomento HandwritingGesture contiene informazioni sulla posizione che puoi utilizzare per determinare in quale punto del testo eseguire il gesto. Ad esempio, SelectGesture fornisce un oggetto RectF che specifica l'intervallo di testo selezionato, mentre InsertGesture un oggetto PointF che specifica l'offset del testo in cui inserire il testo.

    Utilizza i parametri Executor e IntConsumer per inviare il risultato dell'operazione. Quando vengono forniti sia gli argomenti esecutore che consumatore, utilizzalo per chiamare IntConsumer#accept(), ad esempio:

    
    executor.execute { consumer.accept(HANDWRITING_GESTURE_RESULT_SUCCESS) }
    
    
  • HandwritingGesture#getFallbackText() : fornisce il testo di riserva che l'IME esegue il commit nella posizione del cursore se non è presente alcun testo applicabile sotto l'area di un gesto di scrittura a mano libera.

    A volte l'IME non è in grado di determinare se il gesto con lo stilo è destinato a eseguire un'operazione tramite gesti o a scrivere testo a mano libera. Un editor di testo personalizzato è responsabile di determinare l'intenzione dell'utente e di eseguire l'azione appropriata (a seconda del contesto) nella posizione del gesto.

    Ad esempio, se l'IME non riesce a stabilire se l'utente ha intenzione di disegnare un cursore verso il basso ⋁ per eseguire un gesto di inserimento dello spazio o di scrivere a mano la lettera "v", l'IME può inviare un InsertGesture con il testo di riserva "v".

    L'editor deve prima provare a eseguire il gesto di inserimento dello spazio. Se non è possibile eseguire il gesto (ad esempio, non è presente testo nella posizione specificata), l'editor dovrebbe inserire "v" nella posizione del cursore.

  • InputConnection#previewHandwritingGesture(PreviewableHandwritingGesture, CancellationSignal) : visualizza l'anteprima di un gesto in corso. Ad esempio, quando l'utente inizia a disegnare un cerchio intorno al testo, è possibile visualizzare un'anteprima in tempo reale della selezione risultante e aggiornarla continuamente mentre l'utente continua a disegnare. Solo alcuni tipi di gesti sono visualizzabili in anteprima (vedi PreviewableHandwritingGesture).

    Il parametro CancellationSignal può essere utilizzato dall'IME per annullare l'anteprima. Se altri eventi interrompono l'anteprima (ad esempio se il testo viene modificato a livello di programmazione o si verificano nuovi comandi InputConnection), l'editor personalizzato può annullare l'anteprima.

    I gesti di anteprima sono solo per la visualizzazione e non devono cambiare lo stato dell'editor. Ad esempio, un'anteprima di SelectGesture nasconde l'intervallo di selezione corrente dell'editor ed evidenzia l'intervallo di anteprima del gesto. Tuttavia, una volta annullata l'anteprima, l'editor dovrebbe ripristinare l'intervallo di selezione precedente.

Fornisci la posizione del cursore e altri dati sulla posizione

In modalità di scrittura a mano libera, l'IME può richiedere la posizione del cursore e altri dati sulla posizione utilizzando InputConnection#requestCursorUpdates(). L'editor personalizzato risponde con una chiamata a InputMethodManager#updateCursorAnchorInfo(View, CursorAnchorInfo). I dati in CursorAnchorInfo relativi alla scrittura a mano libera con lo stilo vengono forniti tramite i seguenti metodi CursorAnchorInfo.Builder:

  • setInsertionMarkerLocation() : imposta la posizione del cursore. L'IME utilizza il valore per animare la scrittura a mano libera nella posizione del cursore.
  • setEditorBoundsInfo() : imposta i limiti dell'editor e i limiti della scrittura a mano libera. L'IME utilizza questi dati per posizionare la barra degli strumenti per la scrittura a mano libera dell'IME sullo schermo.
  • addVisibleLineBounds() : imposta i limiti di tutte le righe di testo visibili (o parzialmente visibili) dell'editor. L'IME utilizza i limiti di linea per migliorare l'accuratezza del riconoscimento dei gesti di scrittura a mano libera.
  • setTextAppearanceInfo() : imposta l'aspetto del testo con le informazioni derivate dal campo di immissione del testo. L'IME utilizza le informazioni per definire lo stile della scrittura a mano libera.

Mostra l'icona del passaggio del mouse per la scrittura a mano libera con stilo

Visualizza l'icona del passaggio del mouse per la scrittura a mano libera dello stilo quando lo stilo passa sopra i margini della scrittura a mano libera dell'editor di testo personalizzato e l'IME selezionato supporta la scrittura a mano libera con lo stilo (InputMethodManager#isStylusHandwritingAvailable()).

Esegui l'override di View#onResolvePointerIcon() per visualizzare un'icona al passaggio del mouse per la scrittura a mano libera con lo stilo. Nell'override, chiama PointerIcon.getSystemIcon(context, PointerIcon.TYPE_HANDWRITING) per accedere all'icona del passaggio del mouse per la scrittura a mano libera dello stilo del sistema.

Risorse aggiuntive