Edytor metody wprowadzania (IME) to element sterujący, który umożliwia użytkownikom wpisywanie tekstu. Android udostępnia rozszerzalne środowisko metody wprowadzania, które umożliwia aplikacjom udostępnianie użytkownikom alternatywnych metod wprowadzania, takich jak klawiatura ekranowa lub rozpoznawanie mowy. Po zainstalowaniu IME użytkownik może wybrać go w ustawieniach systemu i używać w całym systemie. W danym momencie można włączyć tylko 1 interfejs IME.
Aby dodać metodę IME do systemu Androida, utwórz aplikację na Androida zawierającą klasę rozszerzającą InputMethodService
.
Dodatkowo zwykle tworzysz aktywność „ustawienia”, która przekazuje opcje do usługi IME. Możesz też zdefiniować interfejs ustawień wyświetlany w ramach ustawień systemu.
Na tej stronie znajdziesz informacje na te tematy:
- Cykl życia IME
- Deklarowanie komponentów IME w pliku manifestu aplikacji
- Interfejs IME API
- Projektowanie interfejsu IME
- Wysyłanie tekstu z klawiatury IME do aplikacji
- Praca z podtypami IME
- Inne kwestie związane z IME
Jeśli nie korzystasz z metod wprowadzania danych na ekranie, najpierw przeczytaj artykuł wprowadzający Metody wprowadzania danych na ekranie.
Cykl życia IME
Poniższy diagram przedstawia cykl życia interfejsu IME:
W następnych sekcjach opisujemy, jak zaimplementować interfejs użytkownika i kod powiązany z IME, który przestrzega tego cyklu życia.
Deklarowanie komponentów IME w pliku manifestu
W systemie Android interfejs IME to aplikacja na Androida, która zawiera specjalną usługę IME. Plik manifestu aplikacji musi deklarować usługę, prosić o wymagane uprawnienia, podawać filtr intencji pasujący do działania action.view.InputMethod
oraz metadane określające cechy IME. Aby zapewnić użytkownikowi interfejs ustawień, który pozwala modyfikować działanie IME, możesz zdefiniować aktywność „ustawienia”, którą można uruchomić z Ustawień systemu.
Poniższy fragment kodu deklaruje usługę IME. Usługa prosi o uprawnienie
BIND_INPUT_METHOD
do umożliwienia połączenia usługi z IME z systemem, konfiguruje filtr intencji dopasowujący się 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>
Następny fragment kodu deklaruje aktywność ustawień dla IME. Zawiera ona filtr intencji ACTION_MAIN
, który wskazuje, że ta aktywność jest głównym punktem wejścia do 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 interfejsu.
Interfejs API metody wprowadzania
Klasy związane z interfejsami IME znajdziesz w pakietach android.inputmethodservice
i android.view.inputmethod
. Klasa KeyEvent
jest ważna do obsługi znaków na klawiaturze.
Centralnym elementem IME jest komponent usługi – klasa rozszerzająca klasę InputMethodService
. Oprócz implementowania normalnego cyklu życia usługi ta klasa zawiera metody wywołania zwrotnego, które służą do wyświetlania interfejsu użytkownika IME, obsługi danych wejściowych użytkownika i przesyłania tekstu do pola, które ma fokus. Domyślnie klasa InputMethodService
zapewnia większość implementacji służącej do zarządzania stanem i widocznością IME oraz komunikacji z bieżącym polem wejściowym.
Te zajęcia są też ważne:
BaseInputConnection
- Określa kanał komunikacji z poziomu
InputMethod
do aplikacji, która otrzymuje dane wejściowe. Służy on do odczytywania tekstu wokół kursora, zapisywania tekstu w polu tekstowym i wysyłania do aplikacji nieprzetworzonych zdarzeń. 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ślony przez wystąpienie elementuKeyboard
, które możesz zdefiniować w pliku XML.
Projektowanie interfejsu metody wprowadzania
Istnieją 2 główne elementy wizualne IME: widok wprowadzania i widok kandydatów. Musisz zaimplementować tylko te elementy, które są istotne dla projektowanej metody wprowadzania danych.
Widok danych wejściowych
Widok wprowadzania danych to interfejs, w którym użytkownik wprowadza tekst w postaci kliknięć klawiszy, pisma odręcznego lub gestów. Gdy interfejs IME jest wyświetlany po raz pierwszy, system wywołuje funkcję wywołania zwrotnego onCreateInputView()
. W ramach implementacji tej metody utwórz układ, który ma być wyświetlany w oknie IME, i zwróć go do systemu. Ten 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 funkcji KeyboardView
, która renderuje element Keyboard
.
Widok Kandydaci
Widok kandydatów to interfejs, w którym IME wyświetla potencjalne poprawki lub sugestie słów do wybrania przez użytkownika. W cyklu życia IME system wywołuje funkcję onCreateCandidatesView()
, gdy jest gotowy do wyświetlenia widoku kandydatów. W implementacji tej metody zwracaj układ, który wyświetla sugestie słów, lub zwracaj null, jeśli nie chcesz nic wyświetlać. Domyślną wartością jest odpowiedź null, więc nie musisz jej implementować, jeśli nie podajesz żadnych sugestii.
Uwagi dotyczące projektowania interfejsu
W tej sekcji opisano niektóre kwestie związane z projektowaniem interfejsu użytkownika w przypadku interfejsów IME.
Obsługa wielu rozmiarów ekranu
Interfejs IME musi się skalować do różnych rozmiarów ekranu i działać w orientacji poziomej i pionowej. W trybie IME niepełnoekranowym pozostaw wystarczająco dużo miejsca na pole tekstowe i wszelkie powiązane konteksty, tak aby IME zajmowało nie więcej niż połowę ekranu. W trybie pełnego ekranu w IME nie ma tego problemu.
Obsługa różnych typów danych wejściowych
Pola tekstowe na Androidzie umożliwiają ustawienie konkretnego typu danych, np. tekstu swobodnego, liczb, adresów URL, adresów e-mail i ciągów wyszukiwania. Podczas implementowania nowego IME wykryj typ danych w każdym polu i zapewnij odpowiedni interfejs. Nie musisz jednak konfigurować IME, aby sprawdzić, czy użytkownik wpisuje prawidłowy tekst dla danego typu danych wejściowych. Jest to odpowiedzialność aplikacji, która jest właścicielem pola tekstowego.
Oto na przykład interfejs, który zapewnia układ klawiatury łacińskiej na platformie Android do wprowadzania tekstu:
A tutaj interfejs, który zapewnia klawiatura IME dla języka łacińskiego na platformie Android:
Gdy pole tekstowe zostanie zaznaczone i uruchomiony zostanie IME, system wywołuje funkcję onStartInputView()
, przekazując obiekt EditorInfo
, który zawiera informacje o typie danych i innych atrybutach pola tekstowego. W tym obiekcie pole inputType
zawiera typ danych pola tekstowego.
Pole inputType
to int
, które zawiera wzorce bitów dla różnych ustawień typu danych wejściowych. Aby przetestować typ danych pola tekstowego, zamaskuj go za pomocą stałej TYPE_MASK_CLASS
, na przykład:
Kotlin
inputType and InputType.TYPE_MASK_CLASS
Java
inputType & InputType.TYPE_MASK_CLASS
Wzór bitów typu danych wejściowych może mieć jedną z tych wartości:
TYPE_CLASS_NUMBER
- Pole tekstowe do wpisywania liczb. Jak widać na rysunku 3, w przypadku pól tego typu klawiatura łacińska wyświetla blok numeryczny.
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ą opisane bardziej szczegółowo w dokumentacji referencyjnej dotyczącej InputType
.
Pole inputType
może zawierać inne bity wskazujące wariant typu pola tekstowego, takie jak:
TYPE_TEXT_VARIATION_PASSWORD
- Wariant pola
TYPE_CLASS_TEXT
do wpisywania haseł. Metoda wprowadzania wyświetla dingbats zamiast rzeczywistego 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
TYPE_CLASS_TEXT
służący do wprowadzania tekstu, który aplikacja automatycznie uzupełnia na podstawie słownika, wyszukiwania lub innej funkcji.
Podczas testowania tych wariantów zamaskuj zmienną inputType
odpowiednią stałą. Dostępne stałe maski są wymienione w dokumentacji referencyjnej funkcji InputType
.
Wysyłanie tekstu do aplikacji
Gdy użytkownik wprowadza tekst za pomocą IME, możesz wysyłać tekst do aplikacji, wysyłając pojedyncze zdarzenia naciśnięcia klawisza lub edytując tekst wokół kursora w polu tekstowym aplikacji. W obu przypadkach do przesyłania tekstu użyj instancji InputConnection
. Aby uzyskać tę instancję, zadzwoń pod numer
InputMethodService.getCurrentInputConnection()
.
Edytowanie tekstu wokół kursora
Podczas edytowania istniejącego tekstu przydatne mogą być te metody:
BaseInputConnection
:
-
getTextBeforeCursor()
- Zwraca
CharSequence
zawierający liczbę znaków przed bieżącą pozycją kursora. -
getTextAfterCursor()
- Zwraca
CharSequence
zawierający liczbę żądanych znaków po bieżącej pozycji kursora. -
deleteSurroundingText()
- Usuwanie określonej liczby znaków przed bieżącą pozycją kursora i po niej.
-
commitText()
- Zapisuje
CharSequence
w polu tekstowym i ustala nową pozycję kursora.
Na przykład ten fragment kodu pokazuje, jak zastąpić 4 znaki po lewej stronie kursora tekstem „Cześć!”:
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 zatwierdzaniem
Jeśli Twój system IME przewiduje tekst lub wymaga kilku kroków do ułożenia znaku lub słowa, możesz wyświetlać postępy w polu tekstowym, dopóki użytkownik nie zapisze słowa, a potem zastąpić częściową kompozycję pełnym tekstem. Możesz wyróżnić tekst, dodając do niego element span, gdy przekazujesz go do elementu setComposingText()
.
Ten 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 kluczowych zdarzeń sprzętowych
Mimo że okno metody wprowadzania nie ma wyraźnego fokusa, jako pierwsze odbiera zdarzenia związane z klawiszami sprzętowymi i może je przetwarzać lub przekazywać do aplikacji. Możesz na przykład używać klawiszy kierunkowych do poruszania się po interfejsie podczas wybierania kandydatów do komponowania. Możesz też zablokować klawisz Wstecz, aby zamknąć wszystkie okna dialogowe pochodzące z okna metody wprowadzania.
Aby przechwycić klucze sprzętowe, zastąpij je wartościami z kluczyonKeyDown()
ionKeyUp()
.
Wywołuj metodę super()
w przypadku kluczy, którymi nie chcesz się zajmować samodzielnie.
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ć:
- język, np. pl_PL lub en_US;
- tryb wprowadzania, np. głos, klawiatura lub pismo odręczne;
- inne style, formy lub właściwości związane z IME, takie jak układy klawiatur 10-klawiszowych lub QWERTY;
Tryb może być dowolnym tekstem, np. „klawiatura” lub „głos”. Podtyp może też zawierać kombinację tych typów.
Informacje o podtypie są używane w oknie przełącznika IME, które jest dostępne na pasku powiadomień, oraz w ustawieniach IME. Informacje te umożliwiają też frameworkowi wyświetlenie konkretnego podtypu IME bezpośrednio. Podczas tworzenia IME użyj funkcji podtypu, ponieważ pomaga ona użytkownikowi rozpoznawać różne języki i tryby IME oraz przełączać się między nimi.
Definiowanie podtypów w jednym z plików zasobu XML metody wprowadzania za pomocą elementu <subtype>
. Ten fragment kodu definiuje IME z 2 podtypami: podtyp klawiatury dla lokalizacji angielskiej (amerykańskiej) i podtyp klawiatury dla lokalizacji francuskiej we Francji:
<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 opisane w interfejsie, użyj parametru „%s”, aby uzyskać etykietę podtypu, która jest taka sama jak etykieta lokalizacji podtypu. Pokazuje 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" />
Ten fragment pochodzi z pliku strings.xml
IME. Zasób ciągu tekstowego label_subtype_generic
, który jest używany przez definicję interfejsu metody wprowadzania do ustawienia 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 ustawieniem języka. Na przykład w przypadku dowolnej wersji językowej języka angielskiego wyświetlana nazwa to „English (United States)”.
Wybieranie podtypów metody wprowadzania za pomocą okna powiadomień
System Android zarządza wszystkimi podtypami udostępnianymi przez wszystkie IME. Podtypy IME są traktowane jako tryby IME, do których należą. Użytkownik może przejść z paska powiadomień lub aplikacji Ustawienia do menu dostępnych podtypów IME, jak pokazano na poniższym rysunku:
Wybieranie podtypów IME w ustawieniach systemu
Użytkownik może też kontrolować sposób używania podtypów w panelu ustawień Język i wprowadzanie w ustawieniach systemu:
przełączać się między podtypami IME,
Możesz umożliwić użytkownikom łatwe przełączanie się między typami IME, udostępniając klawisz przełączania, np. ikonę języka w kształcie kuli ziemskiej na klawiaturze. Ułatwia to korzystanie z 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 klucz przełączania.
- Gdy użytkownik kliknie klawisz przełączania, wywołaj funkcję
switchToNextInputMethod()
, przekazując wartość false. Wartość fałsz wskazuje, że system ma traktować wszystkie podtypy w ten sam sposób, niezależnie od tego, do jakiego IME należą. Podanie wartości true powoduje, że system przełącza się między podtypami w bieżącym 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.
- Zapewnij użytkownikom możliwość przełączenia się na inną metodę wprowadzania bezpośrednio w interfejsie metody wprowadzania, ponieważ na urządzeniu może być zainstalowanych kilka metod.
- Szybkie wyświetlanie interfejsu IME. Wstępne wczytywanie dużych zasobów lub wczytywanie ich na żądanie, aby użytkownicy widzieli IME, gdy tylko klikną pole tekstowe. Buforowanie zasobów i widoków na potrzeby kolejnych wywołań metody wprowadzania.
- zwalniać duże alokacje pamięci zaraz 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 ukryte przez kilka sekund.
- Upewnij się, że użytkownicy mogą wpisywać jak najwięcej znaków w języku lub regionie powiązanym z IME. Użytkownicy mogą używać znaków interpunkcyjnych w hasłach lub nazwach użytkowników, dlatego Twoja metoda wprowadzania musi zawierać wiele różnych znaków, aby umożliwić użytkownikom wpisywanie hasła i dostęp do urządzenia.