Benutzerdefinierte Texteditoren

Benutzerdefinierte Texteditoren sind Ansichten, EditText-Komponenten oder WebView Text-Widgets, aber die Texteingabe dennoch unterstützen, indem Sie die onCreateInputConnection() -Callback, der aufgerufen wird, wenn eine Ansicht fokussiert wird und das System eine InputConnection. für die Ansicht.

Ein Aufruf an onCheckIsTextEditor() aus einem benutzerdefinierten Texteditor true zurückgeben.

Unterstützung der Handschrifteingabe mit Eingabestiften in benutzerdefinierten Texteditoren

Android 14 (API-Level 34) und höher unterstützen die Eingabe per Eingabestift in der standardmäßigen Android-Version Komponenten für Texteingabe (siehe Eingabestift in Text Felder). Benutzerdefinierte Texteingabefelder (oder Editoren) erfordern jedoch eine zusätzliche Entwicklung.

So erstellen Sie einen benutzerdefinierten Texteditor:

  1. Handschriftinitiierung aktivieren
  2. Handschriftunterstützung deklarieren
  3. Unterstützung von Handschriftgesten (Auswählen, Löschen, Einfügen usw.)
  4. Cursorposition und andere Positionsdaten für den IME angeben
  5. Symbol für Handschrifteingabe anzeigen

Handschriftinitiierung aktivieren

Besteht eine Ansicht nur aus einem einzigen Texteditor, kann das Ansichtssystem wird die Ansicht automatisch mit dem Eingabestift geschrieben. Andernfalls muss die Ansicht eine eigene Logik zum Initiieren der Handschrift implementieren.

Automatische Handschriftinitiierung

Wenn in einer Ansicht ein einzelner Texteditor und keine anderen Inhalte angezeigt werden, kann die Ansicht in die automatische Handschrifteingabe des Anzeigesystems ein, indem setAutoHandwritingEnabled(true)

Wenn die automatische Handschrift aktiviert ist, beginnt die Bewegung des Eingabestifts in der Ansicht wird der Handschriftmodus automatisch aktiviert. Die Eingabemethode Editor (IME) empfängt die Bewegungsereignisse des Eingabestifts und überträgt den erkannten Text.

<ph type="x-smartling-placeholder">
</ph> Eingabefeld mit umgebenem Rechteck, das die Grenzen für die Erkennung von Eingabestift-Bewegungsereignissen angibt. <ph type="x-smartling-placeholder">
</ph> Abbildung 1: Handschrift innerhalb der Grenzen des Felds EditText.

Initiierung der benutzerdefinierten Handschrift

Wenn eine Ansicht neben einem einzelnen Text mehrere Texteditoren oder Inhalte enthält muss die Ansicht ihre eigene Handschrift-Initiierungslogik implementieren:

  1. Deaktivieren Sie die automatische Handschrifteingabe durch das Anzeigesystem, indem Sie setAutoHandwritingEnabled(false)

  2. Behalten Sie den Überblick über alle Texteditoren, die in der Ansicht sichtbar sind.

  3. Bewegungsereignisse beobachten, die von der Ansicht empfangen werden in dispatchTouchEvent()

    • Wenn sich der Eingabestift innerhalb der Handschriftgrenzen eines Texteditors bewegt, Fokus des Texteditors verschieben (falls er nicht bereits hervorgehoben ist).

    • Wenn der Editor noch nicht im Fokus war, starten Sie den IME des Editors mit einem neuen indem Sie den Aufruf InputMethodManager#restartInput()

    • Starten Sie das Schreiben mit dem Eingabestift, indem Sie InputMethodManager#startStylusHandwriting()

Befindet sich ein Texteditor in einer scrollbaren Ansicht, bewegt sich der Eingabestift innerhalb der als Handschrift und nicht als Scrollen sichtbar. Verwenden Sie ViewParent#requestDisallowInterceptTouchEvent() , um zu verhindern, dass eine scrollbare Ancestor-Ansicht Touch-Events von einem Text abfängt Editor.

API-Details

  • MotionEvent#getToolType() – Gibt an, ob MotionEvent von einem Eingabestift stammt. lautet der Rückgabewert TOOL_TYPE_STYLUS oder TOOL_TYPE_ERASER

  • InputMethodManager#isStylusHandwritingAvailable() – Gibt an, ob der IME die Eingabe per Eingabestift unterstützt. Anruf vor jedem Aufruf von InputMethodManager#startStylusHandwriting() da die Verfügbarkeit der Handschrift geändert wurde.

  • InputMethodManager#startStylusHandwriting() – Der IME wechselt in den Handschriftmodus. Eine ACTION_CANCEL Ein Bewegungsereignis wird an die App gesendet, um die aktuelle Geste abzubrechen. Eingabestift werden keine Bewegungsereignisse mehr an die App gesendet.

    Bewegungsereignisse des Eingabestifts der aktuellen Geste, die bereits ausgelöst wurden: werden die App an den IME weitergeleitet. Der IME ist erforderlich, um die Tinte eines Eingabestifts anzuzeigen Fenster, über das der IME alle folgenden MotionEvent-Objekte empfängt. Der IME überträgt den erkannten handschriftlichen Text mithilfe des InputConnection APIs

    Wenn der IME nicht in den Handschriftmodus wechseln kann, ist dieser Methodenaufruf ein Leerbefehl.

Handschriftunterstützung deklarieren

Beim Ausfüllen der Felder EditorInfo-Argument von Anruf über View#onCreateInputConnection(EditorInfo) setStylusHandwritingEnabled(), um den IME darüber zu informieren, dass der Texteditor Handschrift unterstützt. Unterstützte Touch-Gesten deklarieren mit setSupportedHandwritingGestures() und setSupportedHandwritingGesturePreviews()

Unterstützung von Handschrift-Gesten

IMEs unterstützen verschiedene Handschriftgesten, z. B. das Einkreisen von Text zur Auswahl. oder indem Sie Text durchstreichen, um ihn zu löschen.

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder"> <ph type="x-smartling-placeholder">
</ph> Abbildung 2: Kreis einkreisen, um Text auszuwählen.
<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder"> <ph type="x-smartling-placeholder">
</ph> Abbildung 3: Durchstreichen, um Text zu löschen.

Implementierung von benutzerdefinierten Editoren InputConnection#performHandwritingGesture() und InputConnection#previewHandwritingGesture() um verschiedene HandwritingGesture Typen wie SelectGesture DeleteGesture und InsertGesture.

Deklarieren Sie unterstützte Handschriftgesten beim Ausfüllen des Arguments EditorInfo von View#onCreateInputConnection(EditorInfo) (siehe Handschrift deklarieren) Abschnitt „Support“).

API-Details

  • InputConnection#performHandwritingGesture(HandwritingGesture, Executor, IntConsumer) – Implementiert Gesten. Das Argument HandwritingGesture enthält Standortinformationen, anhand derer Sie feststellen können, führen Sie die Geste aus. SelectGesture stellt beispielsweise ein Objekt RectF, das gibt den ausgewählten Textbereich an und InsertGesture stellt ein PointF-Objekts, das gibt den Textoffset an, an dem Text eingefügt werden soll.

    Verwenden Sie die Operatoren Executor und IntConsumer-Parameter um das Ergebnis des Vorgangs zurückzugeben. Wenn sowohl das Executor als auch Verbraucherargumente bereitgestellt werden, verwenden Sie den Executor, um IntConsumer#accept(), Beispiel:

    
    executor.execute { consumer.accept(HANDWRITING_GESTURE_RESULT_SUCCESS) }
    
    
  • HandwritingGesture#getFallbackText() – Stellt Fallback-Text bereit, den der IME an der Cursorposition per Commit speichert, falls kein unter dem Bereich einer handschriftlichen Touch-Geste angezeigt wird.

    Manchmal kann der IME nicht ermitteln, ob eine Eingabestift-Geste für eine Geste oder handschriftlichen Text. Benutzerdefinierter Text ist der Editor dafür verantwortlich, die Absichten des Nutzers zu bestimmen und je nach Kontext die passende Aktion an der Position der Touch-Geste ausführen.

    Wenn anhand des IMEs beispielsweise nicht ermittelt werden kann, ob der Nutzer wirklich einen nach unten zeigendes Caret-Zeichen ⋁ für eine Leertaste einfügen oder das der Buchstabe „v“ kann der IME eine InsertGesture mit dem Fallback-Text „v“ senden.

    Der Editor sollte zuerst versuchen, die Geste zum Einfügen eines Leerzeichens auszuführen. Wenn die Die Geste kann nicht ausgeführt werden, weil sich an der Stelle beispielsweise kein Text befindet. angegeben ist, sollte der Editor auf "v" zurückgreifen, an der Cursorposition .

  • InputConnection#previewHandwritingGesture(PreviewableHandwritingGesture, CancellationSignal) – Zeigt eine Vorschau einer laufenden Bewegung an. Wenn Nutzende beispielsweise mit dem Zeichnen einen Kreis um einen Text herum, kann eine Live-Vorschau der resultierenden Auswahl und wird kontinuierlich aktualisiert, während der Nutzer weiter zeichnet. Nur bestimmte Gestentypen sind in der Vorschau verfügbar (siehe PreviewableHandwritingGesture)

    Der Parameter CancellationSignal kann vom IME verwendet werden, um den in der Vorschau ansehen. Die Vorschau wird durch andere Ereignisse unterbrochen, z. B. wenn der Text geändert wird. Programmatik oder neue InputConnection-Befehle erfolgt), wird der benutzerdefinierte Editor die Vorschau abbrechen.

    Touch-Gesten für die Vorschau dienen nur der Anzeige und sollten die Einstellungen des Bearbeiters nicht ändern. Bundesstaat. Bei einer Vorschau vom Typ „SelectGesture“ wird beispielsweise die aktuelle Auswahlbereich und hebt den Vorschaubereich für die Touch-Geste hervor. Aber sobald die wird die Vorschau abgebrochen, sollte der Editor den vorherigen Auswahlbereich wiederherstellen.

Cursorposition und andere Positionsdaten angeben

Im Handschriftmodus kann der IME die Cursorposition und andere Positionsdaten anfordern. mit InputConnection#requestCursorUpdates() Der benutzerdefinierte Editor antwortet mit einem Aufruf an InputMethodManager#updateCursorAnchorInfo(View, CursorAnchorInfo) Die Daten in CursorAnchorInfo die für die Handschrifteingabe mit Eingabestiften relevant sind, CursorAnchorInfo.Builder Methoden:

  • setInsertionMarkerLocation() – Legt die Position des Cursors fest. Der IME verwendet den Wert zur Animation. mit der Handschrift an der Cursorposition platzieren.
  • setEditorBoundsInfo() – legt die Grenzen des Editors und die Handschriftgrenzen fest. Der IME verwendet um die Handschrift-Symbolleiste des IME auf dem Bildschirm zu positionieren.
  • addVisibleLineBounds() – Legt die Grenzen aller sichtbaren (oder teilweise sichtbaren) Textzeilen von den Herausgeber. Der IME verwendet die Liniengrenzen, um die Genauigkeit bei der Erkennung Handschriftgesten.
  • setTextAppearanceInfo() – legt die Textdarstellung mit Informationen fest, die aus dem Text abgeleitet sind. Eingabefeld. Der IME verwendet die Informationen, um die handschriftliche Tinte zu gestalten.

Symbol für Handschrifteingabe anzeigen

Symbol für Handschrift einblenden, wenn der Eingabestift über der Handschriftgrenzen des benutzerdefinierten Texteditors und des ausgewählten IMEs unterstützt Schreiben mit Eingabestift (InputMethodManager#isStylusHandwritingAvailable())

Überschreiben View#onResolvePointerIcon() um ein entsprechendes Symbol zu sehen. Rufen Sie in der Überschreibung auf PointerIcon.getSystemIcon(context, PointerIcon.TYPE_HANDWRITING) um auf das Eingabestiftsymbol für die Eingabe per Handschrift zuzugreifen.

Weitere Informationen