Edytor metody wprowadzania (IME) to element sterujący, który umożliwia użytkownikom wpisywanie tekstu. Android udostępnia rozszerzalną platformę metod wprowadzania, która umożliwia aplikacjom udostępnianie użytkownikom alternatywnych metod wprowadzania, takich jak klawiatury ekranowe czy wpisywanie głosowe. Po zainstalowaniu edytorów IME użytkownik może wybrać jeden z nich w ustawieniach systemu i używać go w całym systemie. Jednocześnie można włączyć tylko jeden edytor IME.
Aby dodać IME do systemu Android, utwórz aplikację na Androida zawierającą klasę, która rozszerza klasę InputMethodService
.
Zwykle tworzysz też aktywność „ustawienia”, która przekazuje opcje do usługi IME. Możesz też zdefiniować interfejs ustawień, który będzie wyświetlany w ramach ustawień systemu.
Na tej stronie znajdziesz informacje na te tematy:
- Cykl życia IME
- Deklarowanie komponentów IME w manifeście aplikacji
- Interfejs IME API
- Projektowanie interfejsu IME
- Wysyłanie tekstu z edytora IME do aplikacji
- Praca z podtypami IME
- Inne kwestie dotyczące edytora IME
Jeśli nie masz doświadczenia z IME, przeczytaj najpierw artykuł wprowadzający Metody wprowadzania na ekranie.
Cykl życia IME
Poniższy diagram przedstawia cykl życia IME:

W sekcjach poniżej opisujemy, jak wdrożyć interfejs i kod powiązany z edytorem IME, który jest zgodny z tym cyklem życia.
Deklarowanie komponentów IME w pliku manifestu
W systemie Android IME to aplikacja na Androida, która zawiera specjalną usługę IME. Plik manifestu aplikacji musi deklarować usługę, prosić o niezbędne uprawnienia, zawierać filtr intencji pasujący do działania action.view.InputMethod
oraz zawierać metadane określające cechy klawiatury IME. Dodatkowo, aby udostępnić interfejs ustawień, który umożliwia użytkownikowi modyfikowanie działania edytora IME, możesz zdefiniować aktywność „ustawienia”, którą można uruchomić z Ustawień systemu.
Poniższy fragment kodu deklaruje usługę IME. Żąda uprawnienia
BIND_INPUT_METHOD
umożliwiającego usłudze połączenie IME z systemem, konfiguruje filtr intencji pasujący do działania
android.view.InputMethod
i definiuje metadane 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>
Kolejny fragment kodu deklaruje aktywność ustawień dla IME. Zawiera filtr intencji dla
ACTION_MAIN
, który
wskazuje, że ta aktywność jest głównym punktem wejścia dla aplikacji 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>
Możesz też udostępnić dostęp do ustawień IME bezpośrednio z jego interfejsu.
Interfejs API metody wprowadzania
Klasy specyficzne dla IME znajdują się w pakietach
android.inputmethodservice
i
android.view.inputmethod
. Klasa KeyEvent
jest ważna w przypadku znaków klawiatury.
Centralną częścią IME jest komponent usługi, czyli klasa rozszerzająca InputMethodService
. Oprócz implementowania normalnego cyklu życia usługi ta klasa ma wywołania zwrotne do udostępniania interfejsu IME, obsługi danych wejściowych użytkownika i przesyłania tekstu do pola, które jest aktywne. Domyślnie klasa InputMethodService
zapewnia większość implementacji do zarządzania stanem i widocznością edytora IME oraz komunikacji z bieżącym polem wejściowym.
Ważne są też te klasy:
BaseInputConnection
-
Określa kanał komunikacji z aplikacji, która otrzymuje dane wejściowe.
InputMethod
Używasz go do odczytywania tekstu wokół kursora, zatwierdzania tekstu w polu tekstowym i wysyłania do aplikacji surowych zdarzeń klawiszy. Aplikacje muszą rozszerzać tę klasę, a nie implementować interfejsu podstawowegoInputConnection
. KeyboardView
-
Rozszerzenie
View
, które wyświetla klawiaturę i reaguje na zdarzenia wejściowe użytkownika. Układ klawiatury jest określany przez instancjęKeyboard
, którą możesz zdefiniować w pliku XML.
Projektowanie interfejsu metody wprowadzania
Edytor IME ma 2 główne elementy wizualne: widok wpisywania i widok sugestii. Musisz wdrożyć tylko te elementy, które są istotne dla projektowanej metody wprowadzania.
Widok danych wejściowych
Widok wprowadzania to interfejs, w którym użytkownik wpisuje tekst za pomocą kliknięć klawiszy, pisma odręcznego lub gestów. Gdy IME jest wyświetlany po raz pierwszy, system wywołuje funkcję zwrotną
onCreateInputView()
. W implementacji tej metody utwórz układ, który chcesz wyświetlić w oknie IME, i zwróć go do systemu. Poniższy fragment kodu pokazuje przykład implementacji metody 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; }
W tym przykładzie MyKeyboardView
to instancja niestandardowej implementacji KeyboardView
, która renderuje Keyboard
.
Widok kandydatów
Widok kandydatów to interfejs, w którym IME wyświetla potencjalne poprawki lub sugestie słów, które użytkownik może wybrać. W cyklu życia IME system wywołuje metodę
onCreateCandidatesView()
gdy jest gotowy do wyświetlenia widoku kandydatów. W implementacji tej metody zwróć układ, który wyświetla sugestie słów, lub wartość null, jeśli nie chcesz niczego wyświetlać. Odpowiedź null jest domyślnym zachowaniem, więc nie musisz jej implementować, jeśli nie podajesz sugestii.
Uwagi dotyczące projektowania interfejsu
W tej sekcji opisujemy niektóre kwestie dotyczące projektowania interfejsu użytkownika dla edytorów IME.
Obsługa wielu rozmiarów ekranu
Interfejs IME musi być skalowalny do różnych rozmiarów ekranu i obsługiwać orientację poziomą oraz pionową. W trybie IME niepełnoekranowym pozostaw wystarczająco dużo miejsca, aby aplikacja mogła wyświetlić pole tekstowe i powiązany z nim kontekst. IME nie powinien zajmować więcej niż połowy ekranu. W trybie pełnoekranowym IME nie stanowi to problemu.
Obsługa różnych typów danych wejściowych
Pola tekstowe na Androidzie umożliwiają ustawienie określonego typu danych wejściowych, np. tekst swobodny, liczby, adresy URL, adresy e-mail i ciągi wyszukiwania. Podczas implementacji nowego edytora IME wykrywaj typ danych wejściowych każdego pola i zapewniaj odpowiedni interfejs. Nie musisz jednak konfigurować IME, aby sprawdzać, czy użytkownik wpisuje prawidłowy tekst dla danego typu danych wejściowych. Odpowiedzialność za to ponosi aplikacja, która jest właścicielem pola tekstowego.
Oto na przykład interfejs, który klawiatura IME dla języków europejskich udostępnia na potrzeby wpisywania tekstu na platformie Android:

Oto interfejs, który klawiatura łacińska udostępnia na platformie Android do wprowadzania danych liczbowych:

Gdy pole wejściowe zostanie aktywowane i uruchomi się edytor IME, system wywoła funkcję
onStartInputView()
,
przekazując obiekt
EditorInfo
, który zawiera szczegóły dotyczące typu danych wejściowych i innych atrybutów pola tekstowego. W tym obiekcie pole inputType
zawiera typ danych wejściowych pola tekstowego.
Pole inputType
to int
, które zawiera wzorce bitowe dla różnych ustawień typu danych wejściowych. Aby przetestować typ danych wejściowych pola tekstowego, zamaskuj go za pomocą stałej TYPE_MASK_CLASS
, na przykład tak:
Kotlin
inputType and InputType.TYPE_MASK_CLASS
Java
inputType & InputType.TYPE_MASK_CLASS
Wzorzec bitowy typu danych wejściowych może mieć jedną z kilku wartości, w tym:
TYPE_CLASS_NUMBER
- Pole tekstowe do wpisywania liczb. Jak widać na ilustracji 3, w przypadku pól tego typu klawiatura IME w języku łacińskim wyświetla klawiaturę numeryczną.
TYPE_CLASS_DATETIME
- Pole tekstowe do wpisywania daty i godziny.
TYPE_CLASS_PHONE
- Pole tekstowe do wpisywania numerów telefonów.
TYPE_CLASS_TEXT
- Pole tekstowe do wpisywania dowolnych obsługiwanych znaków.
Te stałe są bardziej szczegółowo opisane w dokumentacji referencyjnej dotyczącej InputType
.
Pole inputType
może zawierać inne bity, które wskazują wariant typu pola tekstowego, np.:
TYPE_TEXT_VARIATION_PASSWORD
- Wariant
TYPE_CLASS_TEXT
do wpisywania haseł. Metoda wprowadzania wyświetla dingbaty zamiast tekstu. TYPE_TEXT_VARIATION_URI
- Wariant
TYPE_CLASS_TEXT
do wpisywania adresów URL i innych identyfikatorów URI. TYPE_TEXT_FLAG_AUTO_COMPLETE
- Wariant elementu
TYPE_CLASS_TEXT
służący do wpisywania tekstu, który aplikacja automatycznie uzupełnia na podstawie słownika, wyszukiwania lub innych funkcji.
Podczas testowania tych wariantów zamaskuj inputType
odpowiednią stałą. Dostępne stałe maski są wymienione w dokumentacji referencyjnej InputType
.
Wysyłanie tekstu do aplikacji
Gdy użytkownik wpisuje tekst za pomocą edytora IME, możesz wysyłać tekst do aplikacji, wysyłając poszczególne zdarzenia klawiszy lub edytując tekst wokół kursora w polu tekstowym aplikacji. W obu przypadkach użyj instancji InputConnection
, aby dostarczyć tekst. Aby uzyskać tę instancję, wywołaj funkcję
InputMethodService.getCurrentInputConnection()
.
Edytowanie tekstu wokół kursora
Podczas edytowania istniejącego tekstu w BaseInputConnection
możesz skorzystać z tych przydatnych metod:
-
getTextBeforeCursor()
- Zwraca
CharSequence
zawierający liczbę żądanych znaków przed bieżącą pozycją kursora. -
getTextAfterCursor()
- Zwraca
CharSequence
zawierający liczbę żądanych znaków znajdujących się za bieżącym położeniem kursora. -
deleteSurroundingText()
- Usuwa określoną liczbę znaków przed i za bieżącą pozycją kursora.
-
commitText()
- Zatwierdza
CharSequence
w polu tekstowym i ustawia nową pozycję kursora.
Na przykład poniższy fragment kodu pokazuje, jak zastąpić 4 znaki po lewej stronie kursora tekstem „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);
Obsługa tworzenia tekstu przed zatwierdzeniem
Jeśli edytor IME przewiduje tekst lub wymaga wykonania kilku czynności w celu utworzenia znaku lub słowa, możesz wyświetlać postęp w polu tekstowym, dopóki użytkownik nie zatwierdzi słowa. Następnie możesz zastąpić częściową kompozycję gotowym tekstem. Możesz wyróżnić tekst, dodając do niego element span, gdy przekazujesz go do funkcji setComposingText()
.
Poniższy fragment kodu pokazuje, jak wyświetlić postęp w polu tekstowym:
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);
Przechwytywanie zdarzeń klawiszy sprzętowych
Mimo że okno metody wprowadzania nie jest aktywne, najpierw otrzymuje zdarzenia klawiszy sprzętowych i może je wykorzystać lub przekazać do aplikacji. Możesz na przykład używać klawiszy strzałek do poruszania się po interfejsie podczas wybierania kandydatów w trakcie pisania. Możesz też przechwycić naciśnięcie przycisku Wstecz, aby zamknąć okna dialogowe pochodzące z okna metody wprowadzania.
Aby przechwytywać klucze sprzętowe, zastąp funkcje
onKeyDown()
i
onKeyUp()
.
W przypadku kluczy, którymi nie chcesz zarządzać samodzielnie, wywołaj metodę super()
.
Tworzenie podtypu IME
Podtypy umożliwiają IME udostępnianie wielu trybów wprowadzania i języków obsługiwanych przez IME. Podtyp może reprezentować:
- kod języka, np. en_US lub fr_FR;
- tryb wprowadzania, np. głosowy, klawiaturowy lub odręczny;
- inne style, formularze lub właściwości wprowadzania danych specyficzne dla IME, takie jak układy klawiatury 10-klawiszowej lub QWERTY;
Tryb może być dowolnym tekstem, np. „klawiatura” lub „głos”. Podtyp może też udostępniać kombinację tych elementów.
Informacje o podtypie są używane w oknie przełącznika IME dostępnym na pasku powiadomień i w ustawieniach IME. Informacje te umożliwiają też platformie bezpośrednie wyświetlanie określonego podtypu edytora IME. Podczas tworzenia IME używaj funkcji podtypu, ponieważ pomaga ona użytkownikowi identyfikować i przełączać się między różnymi językami i trybami IME.
Zdefiniuj podtypy w jednym z plików zasobów XML metody wprowadzania, używając elementu <<subtype>
>. Poniższy fragment kodu definiuje IME z 2 podtypami: podtyp klawiatury dla języka angielskiego (Stany Zjednoczone) i podtyp klawiatury dla języka francuskiego (Francja):
<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>
Aby mieć pewność, że podtypy są prawidłowo oznaczone w interfejsie, użyj ciągu znaków „%s”, aby uzyskać etykietę podtypu, która jest taka sama jak etykieta podtypu w danym języku. Pokazują to 2 kolejne fragmenty kodu. Pierwszy fragment kodu pokazuje część pliku XML metody wprowadzania:
<subtype android:label="@string/label_subtype_generic" android:imeSubtypeLocale="en_US" android:icon="@drawable/icon_en_us" android:imeSubtypeMode="keyboard" />
Kolejny fragment pochodzi z pliku strings.xml
edytora IME. Zasób tekstowy
label_subtype_generic
, który jest używany przez definicję interfejsu metody wprowadzania do ustawiania etykiety
podtypu, jest zdefiniowany w ten sposób:
<string name="label_subtype_generic">%s</string>
To ustawienie powoduje, że wyświetlana nazwa podtypu jest zgodna z ustawieniami regionalnymi. Na przykład w każdej angielskiej wersji językowej wyświetlana nazwa to „English (United States)”.
Wybieranie podtypów IME na pasku powiadomień
System Android zarządza wszystkimi podtypami udostępnianymi przez wszystkie edytory IME. Podtypy edytora IME są traktowane jako tryby edytora IME, do którego należą. Użytkownik może przejść z paska powiadomień lub aplikacji Ustawienia do menu dostępnych podtypów IME, jak pokazano na ilustracji poniżej:

Wybieranie podtypów IME w Ustawieniach systemu
Użytkownik może też określić sposób używania podtypów w panelu ustawień Język i wprowadzanie w ustawieniach systemu:

Przełączanie między podtypami IME
Możesz umożliwić użytkownikom łatwe przełączanie się między podtypami IME, udostępniając klawisz przełączania, np. ikonę języka w kształcie kuli ziemskiej na klawiaturze. Zwiększa to użyteczność klawiatury i jest wygodne dla użytkownika. Aby włączyć przełączanie, wykonaj te czynności:
- Zadeklaruj
supportsSwitchingToNextInputMethod = "true"
w plikach zasobów XML metody wprowadzania. Deklaracja musi wyglądać podobnie do tego fragmentu kodu:<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">
- Wywołaj metodę
shouldOfferSwitchingToNextInputMethod()
. - Jeśli metoda zwróci wartość true, wyświetl przycisk przełączania.
- Gdy użytkownik kliknie klawisz przełączania, wywołanie
switchToNextInputMethod()
, przekazywanie wartości false. Wartość „false” oznacza, że system ma traktować wszystkie podtypy jednakowo, niezależnie od tego, do jakiego edytora IME należą. Określenie wartości „true” wymaga od systemu przełączania się między podtypami w bieżącym edytorze IME.
Ogólne uwagi dotyczące IME
Oto inne kwestie, które warto wziąć pod uwagę podczas wdrażania IME:
- Umożliw użytkownikom ustawianie opcji bezpośrednio w interfejsie IME.
- Umożliw użytkownikom przełączanie się na inny edytor IME bezpośrednio z interfejsu metody wprowadzania, ponieważ na urządzeniu może być zainstalowanych kilka edytorów IME.
- szybko wyświetlać interfejs IME, Wstępnie wczytuj lub wczytuj na żądanie duże zasoby, aby użytkownicy widzieli IME od razu po kliknięciu pola tekstowego. Pamiętaj w pamięci podręcznej zasoby i widoki na potrzeby kolejnych wywołań metody wprowadzania.
- Zwalniaj duże alokacje pamięci natychmiast po ukryciu okna metody wprowadzania, aby aplikacje miały wystarczającą ilość pamięci do działania. Użyj opóźnionej wiadomości, aby zwolnić zasoby, jeśli IME jest ukryty przez kilka sekund.
- Upewnij się, że użytkownicy mogą wpisywać jak najwięcej znaków w języku lub ustawieniach regionalnych powiązanych z IME. Użytkownicy mogą używać znaków interpunkcyjnych w hasłach lub nazwach użytkowników, więc IME musi udostępniać wiele różnych znaków, aby umożliwić użytkownikom wpisanie hasła i uzyskanie dostępu do urządzenia.