Редактор методов ввода (IME) — это пользовательский элемент управления, позволяющий вводить текст. Android предоставляет расширяемую инфраструктуру методов ввода, которая позволяет приложениям предоставлять пользователям альтернативные методы ввода, такие как экранная клавиатура или голосовой ввод. После установки редакторов методов ввода (IME) пользователь может выбрать один из них в системных настройках и использовать его во всей системе. Одновременно может быть включен только один IME.
Чтобы добавить редактор метода ввода (IME) в систему Android, создайте приложение Android, содержащее класс, расширяющий InputMethodService
. Кроме того, обычно создаётся действие «настройки», которое передаёт параметры службе IME. Вы также можете определить пользовательский интерфейс настроек, который будет отображаться как часть системных настроек.
На этой странице рассматриваются следующие темы:
- Жизненный цикл IME
- Объявление компонентов IME в манифесте приложения
- API IME
- Проектирование пользовательского интерфейса IME
- Отправка текста из IME в приложение
- Работа с подтипами IME
- Другие соображения по поводу IME
Если вы не работали с редакторами метода ввода (IME), сначала прочтите вводную статью «Способы экранного ввода» .
Жизненный цикл IME
На следующей диаграмме описан жизненный цикл IME:

В следующих разделах описывается, как реализовать пользовательский интерфейс и код, связанный с IME, который следует этому жизненному циклу.
Объявить компоненты IME в манифесте
В системе Android редактор IME — это приложение Android, содержащее специальную службу IME. Файл манифеста приложения должен декларировать службу, запрашивать необходимые разрешения, предоставлять фильтр намерений, соответствующий действию action.view.InputMethod
, и предоставлять метаданные, определяющие характеристики редактора IME. Кроме того, чтобы предоставить интерфейс настроек, позволяющий пользователю изменять поведение редактора IME, можно определить действие «settings», которое можно запустить из системных настроек.
В следующем фрагменте кода объявляется служба IME. Она запрашивает разрешение BIND_INPUT_METHOD
, позволяющее службе подключить IME к системе, устанавливает фильтр намерений, соответствующий действию android.view.InputMethod
, и определяет метаданные для 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>
В следующем фрагменте кода объявляется действие настроек для IME. В нём есть фильтр намерений для ACTION_MAIN
, который указывает, что это действие является основной точкой входа для приложения 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>
Вы также можете предоставить доступ к настройкам IME непосредственно из его пользовательского интерфейса.
API метода ввода
Классы, специфичные для редакторов метода ввода (IME), находятся в пакетах android.inputmethodservice
и android.view.inputmethod
. Класс KeyEvent
важен для обработки символов клавиатуры.
Центральным компонентом редактора метода ввода (IME) является сервисный компонент — класс, расширяющий InputMethodService
. Помимо реализации обычного жизненного цикла сервиса, этот класс предоставляет обратные вызовы для предоставления пользовательского интерфейса редактора метода ввода (IME), обработки пользовательского ввода и доставки текста в поле, находящееся в фокусе. По умолчанию класс InputMethodService
обеспечивает большую часть реализации для управления состоянием и видимостью редактора метода ввода (IME), а также для взаимодействия с текущим полем ввода.
Также важны следующие классы:
-
BaseInputConnection
- Определяет канал связи от
InputMethod
к приложению, получающему входные данные. Он используется для чтения текста вокруг курсора, фиксации текста в текстовом поле и отправки необработанных событий нажатия клавиш в приложение. Приложения должны расширять этот класс, а не реализовывать базовый интерфейсInputConnection
. -
KeyboardView
- Расширение
View
, которое отображает клавиатуру и реагирует на пользовательский ввод. Раскладка клавиатуры определяется экземпляромKeyboard
, который можно определить в XML-файле.
Разработка пользовательского интерфейса метода ввода
Редактор метода ввода состоит из двух основных визуальных элементов: представления ввода и представления кандидатов . Вам нужно реализовать только те элементы, которые соответствуют разрабатываемому вами методу ввода.
Входной вид
Представление ввода — это пользовательский интерфейс, в котором пользователь вводит текст, нажимая клавиши, используя рукописный ввод или жесты. При первом отображении IME система вызывает функцию обратного вызова onCreateInputView()
. В своей реализации этого метода создайте макет, который должен отображаться в окне IME, и верните его системе. В следующем фрагменте кода показан пример реализации метода onCreateInputView()
:
Котлин
override fun onCreateInputView(): View { return layoutInflater.inflate(R.layout.input, null).apply { if (this is MyKeyboardView) { setOnKeyboardActionListener(this@MyInputMethod) keyboard = latinKeyboard } } }
Ява
@Override public View onCreateInputView() { MyKeyboardView inputView = (MyKeyboardView) getLayoutInflater().inflate(R.layout.input, null); inputView.setOnKeyboardActionListener(this); inputView.setKeyboard(latinKeyboard); return inputView; }
В этом примере MyKeyboardView
— это экземпляр пользовательской реализации KeyboardView
, которая отображает Keyboard
.
Просмотр кандидатов
Представление кандидатов — это пользовательский интерфейс, в котором редактор метода ввода (IME) отображает возможные исправления слов или предложения для выбора пользователем. В жизненном цикле редактора метода ввода (IME) система вызывает onCreateCandidatesView()
, когда готова отобразить представление кандидатов. В своей реализации этого метода верните макет, отображающий предложения слов, или значение null, если вы не хотите ничего отображать. Значение null — это поведение по умолчанию, поэтому вам не нужно реализовывать это, если вы не предоставляете предложения.
Соображения по дизайну пользовательского интерфейса
В этом разделе описываются некоторые аспекты проектирования пользовательского интерфейса для редакторов метода ввода (IME).
Поддержка экранов разных размеров
Пользовательский интерфейс редактора метода ввода должен масштабироваться под разные размеры экрана и поддерживать как альбомную, так и портретную ориентацию. В неполноэкранном режиме редактора метода ввода оставьте достаточно места для отображения текстового поля и связанного с ним контекста, чтобы редактор метода ввода занимал не более половины экрана. В полноэкранном режиме это не проблема.
Обработка различных типов входных данных
Текстовые поля Android позволяют задать определённый тип ввода, например, свободный текст, числа, URL-адреса, адреса электронной почты и строки поиска. При реализации нового редактора метода ввода (IME) определите тип ввода для каждого поля и предоставьте соответствующий интерфейс. Однако вам не нужно настраивать IME для проверки корректности ввода пользователем текста. Это ответственность приложения, которому принадлежит текстовое поле.
Например, вот интерфейс, который Latin IME предоставляет для ввода текста на платформе Android:

А вот интерфейс, который Latin IME предоставляет для числового ввода на платформе Android:

Когда поле ввода получает фокус и запускается редактор метода ввода (IME), система вызывает onStartInputView()
, передавая объект EditorInfo
, содержащий информацию о типе ввода и других атрибутах текстового поля. В этом объекте поле inputType
содержит тип ввода текстового поля.
Поле inputType
— это int
, содержащее битовые шаблоны для различных настроек типа ввода. Чтобы проверить его на соответствие типу ввода текстового поля, замаскируйте его константой TYPE_MASK_CLASS
, например:
Котлин
inputType and InputType.TYPE_MASK_CLASS
Ява
inputType & InputType.TYPE_MASK_CLASS
Битовая комбинация типа ввода может иметь одно из нескольких значений, включая:
-
TYPE_CLASS_NUMBER
- Текстовое поле для ввода чисел. Как показано на рисунке 3, Latin IME отображает цифровую клавиатуру для полей этого типа.
-
TYPE_CLASS_DATETIME
- Текстовое поле для ввода даты и времени.
-
TYPE_CLASS_PHONE
- Текстовое поле для ввода телефонных номеров.
-
TYPE_CLASS_TEXT
- Текстовое поле для ввода любых поддерживаемых символов.
Более подробно эти константы описаны в справочной документации по InputType
.
Поле inputType
может содержать другие биты, указывающие вариант типа текстового поля, например:
-
TYPE_TEXT_VARIATION_PASSWORD
- Вариант
TYPE_CLASS_TEXT
для ввода паролей. Этот метод ввода отображает дингбаты вместо текста. -
TYPE_TEXT_VARIATION_URI
- Вариант
TYPE_CLASS_TEXT
для ввода веб-URL-адресов и других унифицированных идентификаторов ресурсов (URI). -
TYPE_TEXT_FLAG_AUTO_COMPLETE
- Вариант
TYPE_CLASS_TEXT
для ввода текста, который приложение автоматически дополняет из словаря, поиска или другого средства.
При проверке этих вариантов используйте маску inputType
с соответствующей константой. Доступные константы масок перечислены в справочной документации по InputType
.
Отправить текст в приложение
Когда пользователь вводит текст с помощью редактора метода ввода (IME), вы можете отправлять текст в приложение, отправляя отдельные события клавиш или редактируя текст вокруг курсора в текстовом поле приложения. В любом случае используйте экземпляр InputConnection
для передачи текста. Чтобы получить этот экземпляр, вызовите InputMethodService.getCurrentInputConnection()
.
Редактировать текст вокруг курсора
При редактировании существующего текста в BaseInputConnection
пригодятся следующие методы:
-
getTextBeforeCursor()
- Возвращает
CharSequence
, содержащий количество запрошенных символов перед текущей позицией курсора. -
getTextAfterCursor()
- Возвращает
CharSequence
, содержащий количество запрошенных символов, следующих за текущей позицией курсора. -
deleteSurroundingText()
- Удаляет указанное количество символов до и после текущей позиции курсора.
-
commitText()
- Фиксирует
CharSequence
в текстовом поле и устанавливает новую позицию курсора.
Например, в следующем фрагменте показано, как заменить четыре символа слева от курсора текстом «Привет!»:
Котлин
currentInputConnection.also { ic: InputConnection -> ic.deleteSurroundingText(4, 0) ic.commitText("Hello", 1) ic.commitText("!", 1) }
Ява
InputConnection ic = getCurrentInputConnection(); ic.deleteSurroundingText(4, 0); ic.commitText("Hello", 1); ic.commitText("!", 1);
Поддержка написания текста перед фиксацией
Если ваш метод ввода предсказывает текст или требует нескольких шагов для создания глифа или слова, вы можете отображать ход выполнения в текстовом поле до тех пор, пока пользователь не зафиксирует слово, а затем заменить частично составленный текст готовым. Вы можете добавить к тексту особый элемент, добавив к нему интервал при передаче в setComposingText()
.
В следующем фрагменте показано, как отобразить ход выполнения в текстовом поле:
Котлин
currentInputConnection.also { ic: InputConnection -> ic.setComposingText("Composi", 1) ic.setComposingText("Composin", 1) ic.commitText("Composing ", 1) }
Ява
InputConnection ic = getCurrentInputConnection(); ic.setComposingText("Composi", 1); ic.setComposingText("Composin", 1); ic.commitText("Composing ", 1);
Перехват событий аппаратных клавиш
Несмотря на то, что окно метода ввода не имеет явного фокуса, оно сначала получает события аппаратных клавиш и может их использовать или пересылать в приложение. Например, вы можете использовать клавиши со стрелками для навигации по пользовательскому интерфейсу и выбора вариантов при составлении текста. Также может потребоваться перехват клавиши «Назад» для закрытия любых диалоговых окон, созданных в окне метода ввода.
Для перехвата аппаратных клавиш переопределите onKeyDown()
и onKeyUp()
.
Вызовите метод super()
для ключей, которые вы не хотите обрабатывать самостоятельно.
Создать подтип IME
Подтипы позволяют редактору метода ввода (IME) предоставлять доступ к различным режимам ввода и языкам, поддерживаемым редактором метода ввода (IME). Подтип может представлять следующее:
- Локаль, например en_US или fr_FR
- Режим ввода, например, голос, клавиатура или рукописный ввод
- Другие стили ввода, формы или свойства, характерные для IME, такие как 10-клавишная или QWERTY-раскладка клавиатуры
Режим может быть любым, например, «клавиатура» или «голос». Подтип также может представлять собой комбинацию этих вариантов.
Информация о подтипах используется для диалогового окна переключения IME, доступного из панели уведомлений, и для настроек IME. Эта информация также позволяет фреймворку напрямую вызывать определённый подтип IME. При создании IME используйте функцию подтипов, поскольку она помогает пользователю определять и переключаться между различными языками и режимами IME.
Определите подтипы в одном из XML-файлов ресурсов метода ввода, используя элемент <subtype>
. Следующий фрагмент кода определяет редактор метода ввода (IME) с двумя подтипами: подтип клавиатуры для локали «американский английский» и подтип клавиатуры для локали «французский» во Франции:
<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>
Чтобы убедиться, что подтипы правильно помечены в пользовательском интерфейсе, используйте `%s` для получения метки подтипа, совпадающей с меткой локали подтипа. Это показано в следующих двух фрагментах кода. Первый фрагмент демонстрирует часть XML-файла метода ввода:
<subtype android:label="@string/label_subtype_generic" android:imeSubtypeLocale="en_US" android:icon="@drawable/icon_en_us" android:imeSubtypeMode="keyboard" />
Следующий фрагмент — часть файла strings.xml
редактора метода ввода. Строковый ресурс label_subtype_generic
, используемый в определении пользовательского интерфейса метода ввода для установки метки подтипа, определяется следующим образом:
<string name="label_subtype_generic">%s</string>
Этот параметр приводит к тому, что отображаемое имя подтипа соответствует настройкам локали. Например, в любой английской локали отображаемое имя — «Английский (США)».
Выберите подтипы IME на панели уведомлений
Система Android управляет всеми подтипами, предоставляемыми всеми редакторами метода ввода (IME). Подтипы IME рассматриваются как режимы редактора метода ввода (IME), к которому они относятся. Пользователь может перейти из панели уведомлений или приложения «Настройки» в меню доступных подтипов IME, как показано на следующем рисунке:

Выберите подтипы IME в настройках системы.
Пользователь также может управлять использованием подтипов на панели «Настройки языка и ввода » в системных настройках:

Переключение между подтипами IME
Вы можете предоставить пользователям возможность легко переключаться между подтипами редактора метода ввода, добавив клавишу переключения, например, значок языка в форме глобуса на клавиатуре. Это повышает удобство использования клавиатуры и делает её удобной для пользователя. Чтобы включить переключение, выполните следующие действия:
- Объявите параметр
supportsSwitchingToNextInputMethod = "true"
в XML-файлах ресурсов метода ввода. Ваше объявление должно выглядеть примерно так, как показано ниже:<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">
- Вызовите метод
shouldOfferSwitchingToNextInputMethod()
. - Если метод возвращает значение true, отобразите клавишу переключения.
- Когда пользователь нажимает клавишу переключения, вызывается
switchToNextInputMethod()
со значением false. Значение false указывает системе обрабатывать все подтипы одинаково, независимо от того, к какому редактору метода ввода они относятся. Значение true требует, чтобы система циклически перебирала подтипы в текущем редакторе метода ввода.
Общие соображения по поводу IME
Вот еще несколько моментов, которые следует учитывать при внедрении IME:
- Предоставьте пользователям возможность задавать параметры непосредственно из пользовательского интерфейса IME.
- Предоставьте пользователям возможность переключаться на другой IME непосредственно из пользовательского интерфейса метода ввода, поскольку на устройстве может быть установлено несколько IME.
- Быстрое открытие интерфейса редактора метода ввода (IME). Предварительная загрузка или загрузка по запросу любых больших ресурсов, чтобы пользователи видели IME сразу после касания текстового поля. Кэширование ресурсов и представлений для последующих вызовов метода ввода.
- Освобождайте большой объём памяти сразу после скрытия окна метода ввода, чтобы приложениям хватало памяти для работы. Используйте отложенное сообщение для освобождения ресурсов, если редактор метода ввода скрыт в течение нескольких секунд.
- Убедитесь, что пользователи могут вводить как можно больше символов для языка или локали, связанных с редактором метода ввода (IME). Пользователи могут использовать знаки препинания в паролях или именах пользователей, поэтому ваш редактор метода ввода (IME) должен предоставлять множество различных символов, чтобы пользователи могли ввести пароль и получить доступ к устройству.