Niestandardowe edytory tekstu to widoki, które nie są komponentami EditText
ani widżetami tekstu WebView
, ale obsługują wprowadzanie tekstu przez zaimplementowanie wywołania zwrotnego onCreateInputConnection()
, które jest wywoływane, gdy widok jest aktywny, a system wysyła żądanie jego wyświetlenia InputConnection
.
Wywołanie metody onCheckIsTextEditor()
z niestandardowego edytora tekstu powinno zwracać wartość true
.
Obsługa pisma odręcznego rysikiem w niestandardowych edytorach tekstu
Android 14 (poziom interfejsu API 34) i nowsze domyślnie obsługują wprowadzanie tekstu przy użyciu rysika w standardowych komponentach do wprowadzania tekstu na Androidzie (zobacz Wprowadzanie rysika w polach tekstowych). Jednak niestandardowe pola do wprowadzania tekstu (lub edytora) wymagają dodatkowych modyfikacji.
Aby utworzyć niestandardowy edytor tekstu:
- Włącz inicjowanie pisma odręcznego
- Zadeklaruj obsługę pisma odręcznego
- Obsługa gestów pisma odręcznego (zaznaczanie, usuwanie, wstawianie itp.)
- Podaj lokalizację kursora i inne dane o pozycji do IME
- Wyświetlaj ikonę pisma odręcznego rysikiem po najechaniu kursorem
Włącz inicjowanie pisma odręcznego
Jeśli widok obejmuje tylko 1 edytor tekstu, system widoku może automatycznie inicjować w widoku pismo odręczne rysikiem. W przeciwnym razie widok musi implementować własną logikę inicjowania pisma odręcznego.
Automatyczne inicjowanie pisma odręcznego
Jeśli w widoku danych jest tylko 1 edytor tekstu, a nie ma żadnych innych treści, w widoku można włączyć automatyczne inicjowanie pisma odręcznego w systemie widoku, wywołując metodę setAutoHandwritingEnabled(true)
.
Po włączeniu automatycznego pisma odręcznego ruch rysika rozpoczyna się w dowolnym miejscu w obszarze pisma odręcznego, automatycznie uruchamia tryb pisma odręcznego. Edytor metody wprowadzania (IME) odbiera zdarzenia ruchu rysika i zatwierdza rozpoznany tekst.
Inicjowanie niestandardowego pisma odręcznego
Jeśli widok zawiera nie tylko 1 edytor tekstu, ale też wiele innych edytorów tekstu, musi on implementować własną logikę inicjowania pisma odręcznego w ten sposób:
Aby zrezygnować z automatycznego inicjowania pisma odręcznego w systemie wyświetlania, zadzwoń pod numer
setAutoHandwritingEnabled(false)
.Śledź wszystkie edytory tekstu widoczne w widoku.
Monitoruj zdarzenia ruchu otrzymane przez widok w
dispatchTouchEvent()
.Gdy rysik zacznie się przesuwać w granicę pisma odręcznego w edytorze tekstu, zaznacz edytor tekstu (jeśli jeszcze nie jest zaznaczony).
Jeśli edytor nie jest jeszcze zaznaczony, uruchom go ponownie i dodaj nową treść, wywołując metodę
InputMethodManager#restartInput()
.Rozpocznij sesję pisma odręcznego rysikiem, wywołując metodę
InputMethodManager#startStylusHandwriting()
.
Jeśli edytor tekstu znajduje się w widoku z możliwością przewijania, ruch rysika w granicach pisma odręcznego edytującego należy traktować jako pismo odręczne, a nie przewijanie. Użyj metody ViewParent#requestDisallowInterceptTouchEvent()
, aby uniemożliwić przewijany widok elementu nadrzędnego przed przechwytywaniem zdarzeń dotknięcia z edytora tekstu.
Szczegóły interfejsu API
MotionEvent#getToolType()
– wskazuje, czy elementMotionEvent
pochodzi z rysika. W takim przypadku zwracana wartość toTOOL_TYPE_STYLUS
czyTOOL_TYPE_ERASER
.InputMethodManager#isStylusHandwritingAvailable()
– wskazuje, czy edytor IME obsługuje pismo odręczne rysikiem. Wywołuj tę metodę przed każdym wywołaniem funkcjiInputMethodManager#startStylusHandwriting()
, ponieważ dostępność pisma odręcznego mogła się zmienić.InputMethodManager#startStylusHandwriting()
– powoduje, że edytor IME przechodzi w tryb pisma odręcznego. Zdarzenie ruchuACTION_CANCEL
jest wysyłane do aplikacji, aby anulować bieżący gest. Zdarzenia ruchu rysikiem nie są już wysyłane do aplikacji.Zdarzenia ruchu rysika w ramach bieżącego gestu, które zostały już wysłane do aplikacji, są przekazywane do IME. IME jest wymagany, aby pokazać okno atramentu rysikiem, przez które otrzymuje on wszystkie kolejne obiekty
MotionEvent
. IME zatwierdza rozpoznany tekst pismem odręcznym za pomocą interfejsów APIInputConnection
.Jeśli edytor IME nie może włączyć trybu pisma odręcznego, nie można wywołać tej metody.
Zadeklaruj obsługę pisma odręcznego
Podczas wypełniania argumentu EditorInfo
View#onCreateInputConnection(EditorInfo)
wywołaj setStylusHandwritingEnabled()
, aby poinformować IME, że edytor tekstu obsługuje pismo odręczne.
Zadeklaruj obsługiwane gesty za pomocą elementów setSupportedHandwritingGestures()
i setSupportedHandwritingGesturePreviews()
.
Obsługa gestów pisma odręcznego
IME obsługują różne gesty pisma odręcznego, np. zaznaczanie tekstu wokół jego zaznaczenia lub rysowanie po tekście, aby go usunąć.
Edytory niestandardowe implementują
InputConnection#performHandwritingGesture()
i
InputConnection#previewHandwritingGesture()
do obsługi różnych typów
HandwritingGesture
,
na przykład SelectGesture
, DeleteGesture
i InsertGesture
.
Zadeklaruj obsługiwane gesty pisma odręcznego podczas wypełniania argumentu EditorInfo
w polu View#onCreateInputConnection(EditorInfo)
(zobacz sekcję Deklaruj obsługę pisma odręcznego).
Szczegóły interfejsu API
InputConnection#performHandwritingGesture(HandwritingGesture, Executor, IntConsumer)
– implementuje gesty. ArgumentHandwritingGesture
zawiera informacje o lokalizacji, które pozwalają określić, w którym miejscu tekstu należy wykonać gest. Na przykładSelectGesture
udostępnia obiektRectF
, który określa wybrany zakres tekstu, aInsertGesture
obiektPointF
określający przesunięcie tekstu, przy którym ma zostać wstawiony tekst.Użyj parametrów
Executor
iIntConsumer
, aby odesłać wynik operacji. Jeśli podasz zarówno argumenty wykonawcy, jak i klienta, użyj polecenia wykonawcy do wywołaniaIntConsumer#accept()
, na przykład:executor.execute { consumer.accept(HANDWRITING_GESTURE_RESULT_SUCCESS) }
HandwritingGesture#getFallbackText()
– wyświetla tekst zastępczy zatwierdzone przez edytor IME w położeniu kursora, jeśli pod obszarem pisma odręcznego nie ma żadnego tekstu.Czasami edytor IME nie jest w stanie określić, czy gest rysika ma służyć do wykonywania operacji gestu czy do pisania odręcznego tekstu. Za określenie zamiaru użytkownika i wykonanie odpowiedniego działania (w zależności od kontekstu) w miejscu gestu odpowiada edytor niestandardowego tekstu.
Jeśli na przykład edytor IME nie może określić, czy użytkownik miał narysować kursor w dół ⋁, aby wykonać gest wstawiania spacji lub odręcznie napisać literę „v”, edytor IME może wysłać
InsertGesture
z tekstem zastępczym „v”.Edytor powinien najpierw spróbować wykonać gest wstawiania spacji. Jeśli nie można wykonać gestu (na przykład w określonej lokalizacji nie ma tekstu), edytor powinien zamiast tego wstawić „v” w miejscu kursora.
InputConnection#previewHandwritingGesture(PreviewableHandwritingGesture, CancellationSignal)
– wyświetla podgląd trwającego gestu. Gdy na przykład użytkownik zacznie rysować okrąg wokół jakiegoś tekstu, podgląd na żywo wyniku wyboru może być na bieżąco aktualizowany w miarę kontynuacji rysowania. Można wyświetlać podgląd tylko niektórych typów gestów (patrzPreviewableHandwritingGesture
).Edytor IME może używać parametru
CancellationSignal
do anulowania podglądu. Jeśli podgląd zostanie zakłócony przez inne zdarzenia (np. zmiana zostanie automatycznie zmieniona lub pojawi się nowe polecenieInputConnection
), edytor niestandardowy może anulować podgląd.Gesty podglądu są tylko do wyświetlania i nie powinny zmieniać stanu edytora. Na przykład podgląd
SelectGesture
ukrywa bieżący zakres wyboru edytora i wyróżnia zakres podglądu gestów. Gdy jednak podgląd zostanie anulowany, edytor powinien przywrócić poprzedni zakres wyboru.
Podaj lokalizację kursora i inne dane o pozycji
W trybie pisma odręcznego edytor IME może zażądać lokalizacji kursora i innych danych o pozycji, używając InputConnection#requestCursorUpdates()
.
Edytor niestandardowy odpowiada za pomocą wywołania InputMethodManager#updateCursorAnchorInfo(View,
CursorAnchorInfo)
.
Dane w CursorAnchorInfo
dotyczące pisma odręcznego rysikiem są dostarczane za pomocą tych metod CursorAnchorInfo.Builder
:
setInsertionMarkerLocation()
– ustawia lokalizację kursora. Edytor IME używa jej do animowania atramentu w położeniu kursora.setEditorBoundsInfo()
– wyznacza granice edytora i pismo odręczne. Edytor IME używa tych danych do umieszczenia paska narzędzi pisma odręcznego na ekranie.addVisibleLineBounds()
– wyznacza granice wszystkich widocznych (lub częściowo widocznych) wierszy tekstu w edytorze. IME używa granic linii, aby zwiększyć dokładność rozpoznawania gestów pisma odręcznego.setTextAppearanceInfo()
– ustawia wygląd tekstu na podstawie informacji uzyskanych z pola do wprowadzania tekstu. IME używa tych informacji do określania stylu pisma odręcznego.
Wyświetlaj ikonę pisma odręcznego rysikiem po najechaniu kursorem
Wyświetlaj ikonę pisma odręcznego rysika, gdy rysik najedzie na granice pisma odręcznego w niestandardowym edytorze tekstu, a wybrany edytor obsługuje pismo odręczne styl (InputMethodManager#isStylusHandwritingAvailable()
).
Zastąp
View#onResolvePointerIcon()
,
aby uzyskać ikonę najeżdżania kursorem na pismo odręczne rysikiem. W zastępowaniu wywołaj PointerIcon.getSystemIcon(context, PointerIcon.TYPE_HANDWRITING)
, aby uzyskać dostęp do ikony systemu po najechaniu kursorem na pismo odręczne rysika.