Создать метод ввода

Редактор метода ввода (IME) — это пользовательский элемент управления, который позволяет пользователям вводить текст. Android предоставляет расширяемую структуру методов ввода, которая позволяет приложениям предоставлять пользователям альтернативные методы ввода, такие как экранная клавиатура или речевой ввод. После установки IME пользователь может выбрать один из настроек системы и использовать его во всей системе. Одновременно можно включить только один IME.

Чтобы добавить IME в систему Android, создайте приложение Android, содержащее класс, расширяющий InputMethodService . Кроме того, вы обычно создаете действие «settings», которое передает параметры службе IME. Вы также можете определить пользовательский интерфейс настроек, который будет отображаться как часть настроек системы.

На этой странице рассматриваются следующие темы:

Если вы еще не работали с IME, сначала прочитайте вводную статью «Методы ввода на экране» .

Жизненный цикл IME

На следующей диаграмме описан жизненный цикл IME:

Изображение, показывающее жизненный цикл IME.
Рисунок 1. Жизненный цикл IME.

В следующих разделах описывается, как реализовать пользовательский интерфейс и код, связанный с IME, который соответствует этому жизненному циклу.

Объявить компоненты IME в манифесте

В системе Android IME — это приложение Android, содержащее специальную службу IME. Файл манифеста приложения должен объявить службу, запросить необходимые разрешения, предоставить фильтр намерений, соответствующий действию action.view.InputMethod , и предоставить метаданные, определяющие характеристики IME. Кроме того, чтобы предоставить интерфейс настроек, позволяющий пользователю изменять поведение IME, вы можете определить действие «настройки», которое можно запустить из системных настроек.

Следующий фрагмент объявляет службу 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 существует два основных визуальных элемента: представление ввода и представление кандидатов . Вам нужно реализовать только те элементы, которые имеют отношение к проектируемому вами методу ввода.

Представление ввода

Представление ввода — это пользовательский интерфейс, в котором пользователь вводит текст в виде щелчков клавиш, рукописного ввода или жестов. Когда 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, если вы не хотите ничего показывать. Нулевой ответ — это поведение по умолчанию, поэтому вам не нужно его реализовывать, если вы не предоставляете предложения.

Рекомендации по дизайну пользовательского интерфейса

В этом разделе описаны некоторые соображения по проектированию пользовательского интерфейса для IME.

Работа с экранами нескольких размеров

Пользовательский интерфейс вашего IME должен иметь возможность масштабироваться для экранов разных размеров и поддерживать как альбомную, так и портретную ориентацию. В неполноэкранном режиме IME оставьте достаточно места для отображения текстового поля и любого связанного контекста, чтобы IME занимал не более половины экрана. В полноэкранном режиме IME это не проблема.

Обработка различных типов ввода

Текстовые поля Android позволяют установить определенный тип ввода, например текст в произвольной форме, числа, URL-адреса, адреса электронной почты и строки поиска. При реализации нового IME определите тип ввода каждого поля и предоставьте для него соответствующий интерфейс. Однако вам не нужно настраивать IME, чтобы проверять, вводит ли пользователь допустимый текст для типа ввода. За это отвечает приложение, владеющее текстовым полем.

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

Изображение, показывающее ввод текста в латинском IME.
Рисунок 2. Ввод текста IME в латинице.

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

Изображение, показывающее числовой ввод в латинском IME.
Рисунок 3. Числовой ввод латинского IME.

Когда поле ввода получает фокус и запускается IME, система вызывает onStartInputView() , передавая объект EditorInfo , содержащий сведения о типе ввода и других атрибутах текстового поля. В этом объекте поле inputType содержит тип ввода текстового поля.

Поле inputType представляет собой целое int , содержащее битовые комбинации для различных настроек типа ввода. Чтобы проверить тип ввода текстового поля, замаскируйте его константой TYPE_MASK_CLASS , например:

Котлин

inputType and InputType.TYPE_MASK_CLASS

Ява

inputType & InputType.TYPE_MASK_CLASS

Битовый шаблон входного типа может иметь одно из нескольких значений, в том числе:

TYPE_CLASS_NUMBER
Текстовое поле для ввода чисел. Как показано на рисунке 3, латинский 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);

Поддержка составления текста перед фиксацией

Если ваш IME прогнозирует текст или требует нескольких шагов для составления глифа или слова, вы можете отображать ход выполнения в текстовом поле до тех пор, пока пользователь не зафиксирует слово, а затем заменить частичную композицию завершенным текстом. Вы можете уделить тексту особую обработку, добавив к нему интервал при передаче его в 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 IME. Строковый ресурс label_subtype_generic , который используется определением пользовательского интерфейса метода ввода для установки метки подтипа, определяется следующим образом:

<string name="label_subtype_generic">%s</string>

Этот параметр приводит к тому, что отображаемое имя подтипа соответствует настройке языкового стандарта. Например, в любом английском языковом стандарте отображаемое имя — «Английский (США)».

Выберите подтипы IME на панели уведомлений.

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

Изображение меню «Языки и система ввода».
Рисунок 4. Меню «Языки и система ввода ».

Выберите подтипы IME в настройках системы.

Пользователь также может контролировать использование подтипов на панели «Язык и ввод » в настройках системы:

Изображение, показывающее меню выбора языков.
Рисунок 5. Системное меню « Языки»

Переключение между подтипами IME

Вы можете позволить пользователям легко переключаться между подтипами IME, предоставив клавишу переключения, например значок языка в форме глобуса на клавиатуре. Это повышает удобство использования клавиатуры и делает ее удобной для пользователя. Чтобы включить это переключение, выполните следующие действия:

  1. Объявите 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">
  2. Вызовите метод shouldOfferSwitchingToNextInputMethod() .
  3. Если метод возвращает true, отобразите клавишу переключения.
  4. Когда пользователь нажимает клавишу переключения, вызовите switchToNextInputMethod() , передав false. Значение false сообщает системе, что она должна обрабатывать все подтипы одинаково, независимо от того, к какому IME они принадлежат. Указание true требует, чтобы система циклически перебирала подтипы в текущем IME.

Общие соображения по IME

Вот еще несколько вещей, которые следует учитывать при реализации IME:

  • Предоставьте пользователям возможность устанавливать параметры непосредственно из пользовательского интерфейса IME.
  • Предоставьте пользователям возможность переключаться на другой IME непосредственно из пользовательского интерфейса метода ввода, поскольку на устройстве может быть установлено несколько IME.
  • Быстро откройте пользовательский интерфейс IME. Предварительно загружайте или загружайте по требованию любые большие ресурсы, чтобы пользователи видели IME, как только они коснутся текстового поля. Кэшируйте ресурсы и представления для последующих вызовов метода ввода.
  • Освободите большие объемы памяти сразу после того, как окно метода ввода будет скрыто, чтобы у приложений было достаточно памяти для запуска. Используйте отложенное сообщение для освобождения ресурсов, если IME скрыт в течение нескольких секунд.
  • Убедитесь, что пользователи могут вводить как можно больше символов для языка или языкового стандарта, связанного с IME. Пользователи могут использовать знаки препинания в паролях или именах пользователей, поэтому ваш IME должен предоставлять множество разных символов, чтобы пользователи могли вводить пароль и получать доступ к устройству.
,

Редактор метода ввода (IME) — это пользовательский элемент управления, который позволяет пользователям вводить текст. Android предоставляет расширяемую структуру методов ввода, которая позволяет приложениям предоставлять пользователям альтернативные методы ввода, такие как экранная клавиатура или речевой ввод. После установки IME пользователь может выбрать один из настроек системы и использовать его во всей системе. Одновременно можно включить только один IME.

Чтобы добавить IME в систему Android, создайте приложение Android, содержащее класс, расширяющий InputMethodService . Кроме того, вы обычно создаете действие «settings», которое передает параметры службе IME. Вы также можете определить пользовательский интерфейс настроек, который будет отображаться как часть настроек системы.

На этой странице рассматриваются следующие темы:

Если вы еще не работали с IME, сначала прочитайте вводную статью «Методы ввода на экране» .

Жизненный цикл IME

На следующей диаграмме описан жизненный цикл IME:

Изображение, показывающее жизненный цикл IME.
Рисунок 1. Жизненный цикл IME.

В следующих разделах описывается, как реализовать пользовательский интерфейс и код, связанный с IME, который соответствует этому жизненному циклу.

Объявить компоненты IME в манифесте

В системе Android IME — это приложение Android, содержащее специальную службу IME. Файл манифеста приложения должен объявить службу, запросить необходимые разрешения, предоставить фильтр намерений, соответствующий действию action.view.InputMethod , и предоставить метаданные, определяющие характеристики IME. Кроме того, чтобы предоставить интерфейс настроек, который позволяет пользователю изменять поведение IME, вы можете определить действие «настройки», которое можно запустить из системных настроек.

Следующий фрагмент объявляет службу 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 существует два основных визуальных элемента: представление ввода и представление кандидатов . Вам нужно реализовать только те элементы, которые имеют отношение к проектируемому вами методу ввода.

Представление ввода

Представление ввода — это пользовательский интерфейс, в котором пользователь вводит текст в виде щелчков клавиш, рукописного ввода или жестов. Когда 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, если вы не хотите ничего показывать. Нулевой ответ — это поведение по умолчанию, поэтому вам не нужно его реализовывать, если вы не предоставляете предложения.

Рекомендации по дизайну пользовательского интерфейса

В этом разделе описаны некоторые соображения по проектированию пользовательского интерфейса для IME.

Работа с экранами нескольких размеров

Пользовательский интерфейс вашего IME должен иметь возможность масштабироваться для экранов разных размеров и поддерживать как альбомную, так и портретную ориентацию. В неполноэкранном режиме IME оставьте приложению достаточно места для отображения текстового поля и любого связанного контекста, чтобы IME занимал не более половины экрана. В полноэкранном режиме IME это не проблема.

Обработка различных типов ввода

Текстовые поля Android позволяют установить определенный тип ввода, например текст в произвольной форме, числа, URL-адреса, адреса электронной почты и строки поиска. При реализации нового IME определите тип ввода каждого поля и предоставьте для него соответствующий интерфейс. Однако вам не нужно настраивать IME, чтобы проверять, вводит ли пользователь допустимый текст для типа ввода. За это отвечает приложение, владеющее текстовым полем.

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

Изображение, показывающее ввод текста в латинском IME.
Рисунок 2. Ввод текста IME в латинице.

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

Изображение, показывающее числовой ввод в латинском IME.
Рисунок 3. Числовой ввод латинского IME.

Когда поле ввода получает фокус и запускается IME, система вызывает onStartInputView() , передавая объект EditorInfo , содержащий сведения о типе ввода и других атрибутах текстового поля. В этом объекте поле inputType содержит тип ввода текстового поля.

Поле inputType представляет собой целое int , содержащее битовые комбинации для различных настроек типа ввода. Чтобы проверить тип ввода текстового поля, замаскируйте его константой TYPE_MASK_CLASS , например:

Котлин

inputType and InputType.TYPE_MASK_CLASS

Ява

inputType & InputType.TYPE_MASK_CLASS

Битовый шаблон входного типа может иметь одно из нескольких значений, в том числе:

TYPE_CLASS_NUMBER
Текстовое поле для ввода чисел. Как показано на рисунке 3, латинский 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);

Поддержка составления текста перед фиксацией

Если ваш IME прогнозирует текст или требует нескольких шагов для составления глифа или слова, вы можете отображать ход выполнения в текстовом поле до тех пор, пока пользователь не зафиксирует слово, а затем заменить частичную композицию завершенным текстом. Вы можете уделить тексту особую обработку, добавив к нему интервал при передаче его в 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 IME. Строковый ресурс label_subtype_generic , который используется определением пользовательского интерфейса метода ввода для установки метки подтипа, определяется следующим образом:

<string name="label_subtype_generic">%s</string>

Этот параметр приводит к тому, что отображаемое имя подтипа соответствует настройке языкового стандарта. Например, в любом английском языковом стандарте отображаемое имя — «Английский (США)».

Выберите подтипы IME на панели уведомлений.

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

Изображение меню «Языки и система ввода».
Рисунок 4. Меню «Языки и система ввода ».

Выберите подтипы IME в настройках системы.

Пользователь также может контролировать использование подтипов на панели «Язык и ввод » в настройках системы:

Изображение, показывающее меню выбора языков.
Рисунок 5. Системное меню « Языки»

Переключение между подтипами IME

Вы можете позволить пользователям легко переключаться между подтипами IME, предоставив клавишу переключения, например значок языка в форме глобуса на клавиатуре. Это повышает удобство использования клавиатуры и делает ее удобной для пользователя. Чтобы включить это переключение, выполните следующие действия:

  1. Объявите 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">
  2. Вызовите метод shouldOfferSwitchingToNextInputMethod() .
  3. Если метод возвращает true, отобразите клавишу переключения.
  4. Когда пользователь нажимает клавишу переключения, вызовите switchToNextInputMethod() , передав false. Значение false сообщает системе, что она должна обрабатывать все подтипы одинаково, независимо от того, к какому IME они принадлежат. Указание true требует, чтобы система циклически перебирала подтипы в текущем IME.

Общие соображения по IME

Вот еще несколько вещей, которые следует учитывать при реализации IME:

  • Предоставьте пользователям возможность устанавливать параметры непосредственно из пользовательского интерфейса IME.
  • Предоставьте пользователям возможность переключаться на другой IME непосредственно из пользовательского интерфейса метода ввода, поскольку на устройстве может быть установлено несколько IME.
  • Быстро откройте пользовательский интерфейс IME. Предварительно загружайте или загружайте по требованию любые большие ресурсы, чтобы пользователи видели IME, как только они коснутся текстового поля. Кэшируйте ресурсы и представления для последующих вызовов метода ввода.
  • Освободите большие объемы памяти сразу после того, как окно метода ввода будет скрыто, чтобы у приложений было достаточно памяти для запуска. Используйте отложенное сообщение для освобождения ресурсов, если IME скрыт в течение нескольких секунд.
  • Убедитесь, что пользователи могут вводить как можно больше символов для языка или языкового стандарта, связанного с IME. Пользователи могут использовать знаки препинания в паролях или именах пользователей, поэтому ваш IME должен предоставлять множество разных символов, чтобы пользователи могли вводить пароль и получать доступ к устройству.
,

Редактор метода ввода (IME) — это пользовательский элемент управления, который позволяет пользователям вводить текст. Android предоставляет расширяемую структуру методов ввода, которая позволяет приложениям предоставлять пользователям альтернативные методы ввода, такие как экранная клавиатура или речевой ввод. После установки IME пользователь может выбрать один из настроек системы и использовать его во всей системе. Одновременно можно включить только один IME.

Чтобы добавить IME в систему Android, создайте приложение Android, содержащее класс, расширяющий InputMethodService . Кроме того, вы обычно создаете действие «settings», которое передает параметры службе IME. Вы также можете определить пользовательский интерфейс настроек, который будет отображаться как часть настроек системы.

На этой странице рассматриваются следующие темы:

Если вы еще не работали с IME, сначала прочитайте вводную статью «Методы ввода на экране» .

Жизненный цикл IME

На следующей диаграмме описан жизненный цикл IME:

Изображение, показывающее жизненный цикл IME.
Рисунок 1. Жизненный цикл IME.

В следующих разделах описывается, как реализовать пользовательский интерфейс и код, связанный с IME, который соответствует этому жизненному циклу.

Объявить компоненты IME в манифесте

В системе Android IME — это приложение Android, содержащее специальную службу IME. Файл манифеста приложения должен объявить службу, запросить необходимые разрешения, предоставить фильтр намерений, соответствующий действию action.view.InputMethod , и предоставить метаданные, определяющие характеристики IME. Кроме того, чтобы предоставить интерфейс настроек, который позволяет пользователю изменять поведение IME, вы можете определить действие «настройки», которое можно запустить из системных настроек.

Следующий фрагмент объявляет службу 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 обратно в приложение, которое получает его вход. Вы используете его для чтения текста вокруг курсора, совершаете текст в текстовое поле и отправляете события клавиш RAW в приложение. Приложения должны расширять этот класс, а не реализовывать базовый интерфейс InputConnection .
KeyboardView
Расширение View , которое отображает клавиатуру и отвечает на события ввода пользователей. Макет клавиатуры определяется экземпляром Keyboard , который вы можете определить в файле XML.

Разработать пользовательский интерфейс метода ввода

Есть два основных визуальных элемента для IME: представление входных и кандидатов . Вам нужно только реализовать элементы, которые имеют отношение к методу ввода, который вы проектируете.

Входной вид

Входным представлением является пользовательский интерфейс, в котором пользователь вводит текст в форме кликов, почерков или жестов. Когда 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, если вы не хотите ничего показывать. Нулевой ответ - это поведение по умолчанию, поэтому вам не нужно реализовать это, если вы не предоставляете предложения.

Соображения дизайна пользовательского интерфейса

В этом разделе описываются некоторые соображения дизайна пользовательского интерфейса для IMES.

Обрабатывать несколько размеров экрана

Пользовательский интерфейс для вашего IME должен иметь возможность масштабироваться для разных размеров экрана и обрабатывать как ландшафт, так и ориентации на портретов. В неполноценном режиме IME оставьте достаточно места для приложения, чтобы показать текстовое поле и любой связанный контекст, так что не более половины экрана занята IME. В полноэкранном режиме IME это не проблема.

Обрабатывать различные типы вводов

Поля текста Android позволяют установить конкретный тип ввода, такой как текст бесплатной формы, номера, URL-адреса, адреса электронной почты и строки поиска. Когда вы реализуете новый IME, обнаружите тип ввода каждого поля и предоставьте соответствующий интерфейс для него. Тем не менее, вам не нужно настроить IME, чтобы проверить, входит ли пользователь допустимый текст для типа ввода. Это обязанность приложения, которое владеет текстовым полем.

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

Изображение, показывающее ввод текста на латинском IME
Рисунок 2. Латинский ввод текста.

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

Изображение, показывающее числовой вход на латинском IME
Рисунок 3. Латинский численное вход.

Когда поле ввода получает фокус, и ваш IME запускается, система вызывает onStartInputView() , передавая объект EditorInfo , который содержит подробную информацию о типе ввода и других атрибутах текстового поля. В этом объекте поле inputType содержит тип ввода текстового поля.

Поле inputType - это int , который содержит битовые шаблоны для различных настроек типа ввода. Чтобы проверить его для типа ввода текстового поля, замаскируйте его постоянным TYPE_MASK_CLASS , например:

Котлин

inputType and InputType.TYPE_MASK_CLASS

Ява

inputType & InputType.TYPE_MASK_CLASS

У шаблона бита типа ввода может быть одно из нескольких значений, в том числе:

TYPE_CLASS_NUMBER
Текстовое поле для ввода чисел. Как показано на рисунке 3, латинский 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);

Поддержка сочинения текста перед совершением

Если ваш IME предсказывает текст или требует нескольких шагов для составления глифа или слова, вы можете показать прогресс в текстовом поле до тех пор, пока пользователь не получит слово, а затем вы можете заменить частичную композицию завершенным текстом. Вы можете дать особую обработку тексту, добавив к нему пролет , когда вы передаете его в 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" />

Следующий фрагмент является частью файла ime strings.xml . Ресурс String Resource label_subtype_generic , который используется определением пользовательского интерфейса метода ввода для установки метки подтипа, определяется как следующее:

<string name="label_subtype_generic">%s</string>

Этот параметр приводит к тому, что отображающее имя подтипа соответствует настройке локализации. Например, в любом английском локале отображаемое имя «Английский (Соединенные Штаты)».

Выберите подтипы IME из панели уведомлений

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

Изображение, показывающее меню «Языки и системы ввода»
Рисунок 4. Меню «Языки и системы ввода ».

Выберите подтипы IME из настройки системы

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

Изображение, показывающее меню выбора языков
Рисунок 5. Меню системы языков

Переключение между подтипами IME

Вы можете позволить пользователям легко переключаться между подтипами IME, предоставляя ключ переключения, такой как значок языка в форме глобуса на клавиатуре. Это улучшает удобство использования клавиатуры и удобно для пользователя. Чтобы включить это переключение, выполните следующие шаги:

  1. Declare 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">
  2. Вызовите метод shouldOfferSwitchingToNextInputMethod() .
  3. Если метод возвращает true, отобразите ключ переключения.
  4. Когда пользователь нажимает на клавишу переключения, вызовите switchToNextInputMethod() , передавая false. Значение FALSE говорит системе для обращения со всеми подтипами в равной степени, независимо от того, к чему они принадлежат. Указание True требует, чтобы система прокатилась через подтипы в текущем IME.

Общие соображения IME

Вот другие вещи, которые следует учитывать, когда вы реализуете свой IME:

  • Предоставьте пользователям возможность установить параметры непосредственно из пользовательского интерфейса IME.
  • Предоставьте пользователям возможность переключиться на другой IME непосредственно из пользовательского интерфейса метода ввода, потому что на устройстве могут быть установлены несколько IME.
  • Быстро заведите пользовательский интерфейс IME. Предварительная нагрузка или загрузка по требованию любых больших ресурсов, чтобы пользователи видели IME, как только они нажимают на текстовое поле. Кэш -ресурсы и представления для последующих вызовов метода ввода.
  • Выпустите большие распределения памяти сразу после того, как окно метода ввода скрыто, чтобы приложения имели достаточное количество памяти для запуска. Используйте отложенное сообщение для выпуска ресурсов, если IME скрыт в течение нескольких секунд.
  • Убедитесь, что пользователи могут ввести как можно больше символов для языка или локализации, связанного с IME. Пользователи могут использовать пунктуацию в паролях или именах пользователей, поэтому ваш IME должен предоставить много разных символов, чтобы пользователи ввели пароль и доступ к устройству.
,

Редактор метода ввода (IME) - это пользовательский элемент управления, который позволяет пользователям вводить текст. Android предоставляет расширяемую структуру ввода-метода, которая позволяет приложениям предоставлять пользователям альтернативные методы ввода, такие как экранические клавиатуры или речевой ввод. После установки IMES пользователь может выбрать один из настройки системы и использовать его по всей системе. Только один IME может быть включен за раз.

Чтобы добавить IME в систему Android, создайте приложение для Android, содержащее класс, который расширяет InputMethodService . Кроме того, вы обычно создаете деятельность «настройки», которая передает параметры в службу IME. Вы также можете определить пользовательский интерфейс настроек, который отображается как часть настроек системы.

Эта страница охватывает следующие темы:

Если вы не работали с IMES, сначала прочитайте вступительную статью о методах ввода экрана .

IME жизненный цикл

На следующей диаграмме описывается жизненный цикл IME:

Изображение, показывающее жизненный цикл IME.
Рисунок 1. Жизненный цикл IME.

В следующих разделах описывается, как реализовать пользовательский интерфейс и код, связанный с IME, который следует за этим жизненным циклом.

Объявить компоненты IME в манифесте

В системе Android IME - это приложение для Android, которое содержит специальную услугу IME. Манифестный файл приложения должен объявить Сервис, запрашивать необходимые разрешения, предоставить фильтр намерения, который соответствует действию action.view.InputMethod и предоставляет метаданные, которые определяют характеристики IME. Кроме того, чтобы предоставить интерфейс настроек, который позволяет пользователю изменять поведение IME, вы можете определить деятельность «Настройки», которая может быть запущена из настройки системы.

Следующий фрагмент объявляет услугу 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 метода ввода API

Классы, специфичные для IME, находятся в пакетах android.inputmethodservice и android.view.inputmethod . Класс KeyEvent важен для обработки символов клавиш.

Центральной частью IME является сервисный компонент - класс, который расширяет InputMethodService . В дополнение к реализации обычного жизненного цикла обслуживания, в этом классе есть обратные вызовы для предоставления пользовательского интерфейса IME, обработки ввода пользователя и доставки текста в поле, которое имеет фокус. По умолчанию класс InputMethodService предоставляет большую часть реализации для управления состоянием и видимости IME и общения с текущим полем ввода.

Следующие классы также важны:

BaseInputConnection
Определяет канал связи от InputMethod обратно в приложение, которое получает его вход. Вы используете его для чтения текста вокруг курсора, совершаете текст в текстовое поле и отправляете события клавиш RAW в приложение. Приложения должны расширять этот класс, а не реализовывать базовый интерфейс InputConnection .
KeyboardView
Расширение View , которое отображает клавиатуру и отвечает на события ввода пользователей. Макет клавиатуры определяется экземпляром Keyboard , который вы можете определить в файле XML.

Разработать пользовательский интерфейс метода ввода

Есть два основных визуальных элемента для IME: представление входных и кандидатов . Вам нужно только реализовать элементы, которые имеют отношение к методу ввода, который вы проектируете.

Входной вид

Входным представлением является пользовательский интерфейс, в котором пользователь вводит текст в форме кликов, почерков или жестов. Когда 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, если вы не хотите ничего показывать. Нулевой ответ - это поведение по умолчанию, поэтому вам не нужно реализовать это, если вы не предоставляете предложения.

Соображения дизайна пользовательского интерфейса

В этом разделе описываются некоторые соображения дизайна пользовательского интерфейса для IMES.

Обрабатывать несколько размеров экрана

Пользовательский интерфейс для вашего IME должен иметь возможность масштабироваться для разных размеров экрана и обрабатывать как ландшафт, так и ориентации на портретов. В неполноценном режиме IME оставьте достаточно места для приложения, чтобы показать текстовое поле и любой связанный контекст, так что не более половины экрана занята IME. В полноэкранном режиме IME это не проблема.

Обрабатывать различные типы вводов

Поля текста Android позволяют установить конкретный тип ввода, такой как текст бесплатной формы, номера, URL-адреса, адреса электронной почты и строки поиска. Когда вы реализуете новый IME, обнаружите тип ввода каждого поля и предоставьте соответствующий интерфейс для него. Тем не менее, вам не нужно настроить IME, чтобы проверить, входит ли пользователь допустимый текст для типа ввода. Это обязанность приложения, которое владеет текстовым полем.

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

Изображение, показывающее ввод текста на латинском IME
Рисунок 2. Латинский ввод текста.

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

Изображение, показывающее числовой вход на латинском IME
Рисунок 3. Латинский численное вход.

Когда поле ввода получает фокус, и ваш IME запускается, система вызывает onStartInputView() , передавая объект EditorInfo , который содержит подробную информацию о типе ввода и других атрибутах текстового поля. В этом объекте поле inputType содержит тип ввода текстового поля.

Поле inputType - это int , который содержит битовые шаблоны для различных настроек типа ввода. Чтобы проверить его для типа ввода текстового поля, замаскируйте его постоянным TYPE_MASK_CLASS , например:

Котлин

inputType and InputType.TYPE_MASK_CLASS

Ява

inputType & InputType.TYPE_MASK_CLASS

У шаблона бита типа ввода может быть одно из нескольких значений, в том числе:

TYPE_CLASS_NUMBER
Текстовое поле для ввода чисел. Как показано на рисунке 3, латинский 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);

Поддержка сочинения текста перед совершением

Если ваш IME предсказывает текст или требует нескольких шагов для составления глифа или слова, вы можете показать прогресс в текстовом поле до тех пор, пока пользователь не получит слово, а затем вы можете заменить частичную композицию завершенным текстом. Вы можете дать особую обработку тексту, добавив к нему пролет , когда вы передаете его в 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" />

Следующий фрагмент является частью файла ime strings.xml . Ресурс String Resource label_subtype_generic , который используется определением пользовательского интерфейса метода ввода для установки метки подтипа, определяется как следующее:

<string name="label_subtype_generic">%s</string>

Этот параметр приводит к тому, что отображающее имя подтипа соответствует настройке локализации. Например, в любом английском локале отображаемое имя «Английский (Соединенные Штаты)».

Выберите подтипы IME из панели уведомлений

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

Изображение, показывающее меню «Языки и системы ввода»
Рисунок 4. Меню «Языки и системы ввода ».

Выберите подтипы IME из настройки системы

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

Изображение, показывающее меню выбора языков
Рисунок 5. Меню системы языков

Переключение между подтипами IME

Вы можете позволить пользователям легко переключаться между подтипами IME, предоставляя ключ переключения, такой как значок языка в форме глобуса на клавиатуре. Это улучшает удобство использования клавиатуры и удобно для пользователя. Чтобы включить это переключение, выполните следующие шаги:

  1. Declare 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">
  2. Вызовите метод shouldOfferSwitchingToNextInputMethod() .
  3. Если метод возвращает true, отобразите ключ переключения.
  4. Когда пользователь нажимает на клавишу переключения, вызовите switchToNextInputMethod() , передавая false. Значение FALSE говорит системе для обращения со всеми подтипами в равной степени, независимо от того, к чему они принадлежат. Указание True требует, чтобы система прокатилась через подтипы в текущем IME.

Общие соображения IME

Вот другие вещи, которые следует учитывать, когда вы реализуете свой IME:

  • Предоставьте пользователям возможность установить параметры непосредственно из пользовательского интерфейса IME.
  • Предоставьте пользователям возможность переключиться на другой IME непосредственно из пользовательского интерфейса метода ввода, потому что на устройстве могут быть установлены несколько IME.
  • Быстро заведите пользовательский интерфейс IME. Предварительная нагрузка или загрузка по требованию любых больших ресурсов, чтобы пользователи видели IME, как только они нажимают на текстовое поле. Кэш -ресурсы и представления для последующих вызовов метода ввода.
  • Выпустите большие распределения памяти сразу после того, как окно метода ввода скрыто, чтобы приложения имели достаточное количество памяти для запуска. Используйте отложенное сообщение для выпуска ресурсов, если IME скрыт в течение нескольких секунд.
  • Убедитесь, что пользователи могут ввести как можно больше символов для языка или локализации, связанного с IME. Пользователи могут использовать пунктуацию в паролях или именах пользователей, поэтому ваш IME должен предоставить много разных символов, чтобы пользователи ввели пароль и доступ к устройству.