Создание пользовательской клавиатуры на Android ...
Большинство устройств Android не имеют клавиатуры. Вместо этого они полагаются на виртуальную или экранную клавиатуру для ввода текста. Если вы используете персонализацию Android, то знание о создании пользовательской, приятной клавиатуры может вывести ваше хобби на совершенно новый уровень.
Используя Android SDK, вы можете быстро создать экранную клавиатуру с удивительно небольшим количеством строк кода, поскольку SDK выполняет множество задач простого уровня, таких как распознавание касаний клавиш, рисование клавиатуры и установление соединений между клавиатурой и поля ввода.
В этом уроке вы узнаете, как создать полноценную функциональную клавиатуру, которая может служить для вас на вашем устройстве Android по умолчанию.
1. Предпосылки
Вам понадобится комплект Eclipse ADT Bundle. Вы можете загрузить его с веб-сайта разработчика Android.
2. Создать новый проект
Запустите программу Eclipse и создайте новое приложение для Android. Назовите это приложение SimpleKeyboard. Убедитесь, что вы выбрали уникальное имя пакета. Установите минимально необходимый SDK на значение Android 2.2 и установите целевой SDK на значение Android 4.4
Это приложение не будет иметь никаких действий, поэтому снимите флажок с Создать мероприятие и нажмите Готово.
3. Отредактируйте манифест
Экранная клавиатура рассматривается как Input Method Editor (IME) для операционной системы Android. IME объявляется как Service
в AndroidManifest.xml, который использует разрешение BIND_INPUT_METHOD
и отвечает за android.view.InputMethod
.
Добавьте следующие строки в тег application
файла манифеста:
<service android:name=".SimpleIME" android:label="@string/simple_ime" android:permission="android.permission.BIND_INPUT_METHOD" > <meta-data android:name="android.view.im" android:resource="@xml/method"/> <intent-filter> <action android:name="android.view.InputMethod" /> </intent-filter> </service>
4. Создайте метод.
Тег service
в файле манифеста содержит meta-data
, который ссылается на файл XML с именем method.xml. Без этого файла операционная система Android не признает наш Service
в качестве действительной IME-службы. Файл содержит сведения о методе ввода и его подтипах. Для перевода нашей клавиатуры на другой язык мы выбираем один подтип en_US. Создайте каталог res/xml, если его нет, и добавьте к нему файл method.xml. Содержимое файла должно быть следующим:
<?xml version="1.0" encoding="utf-8"?><input-method xmlns:android="https://schemas.android.com/apk/res/android"> <subtype android:label="@string/subtype_en_US" android:imeSubtypeLocale="en_US"android:imeSubtypeMode="keyboard" /></input-method>
5. Редактирование строк.xml
Строки, используемые этим приложением, определены в файле theres/values/strings.xml. Нам понадобятся следующие три строки:
- имя приложения
- ярлык IME
- ярлык подтипа IME
Обновите файл strings.xml, чтобы он имел следующее содержимое:
<resources> <string name="app_name">SimpleKeyboard</string> <string name="simple_ime">Simple IME</string> <string name="subtype_en_US">English (US)</string></resources>
6. Определите макет клавиатуры
Макет нашей клавиатуры содержит только KeyboardView
. Атрибут layout_alignParentBottom
имеет значение true
, чтобы клавиатура отображалась в нижней части экрана.
Создайте файл с именем res/layout/keyboard.xml и замените его содержимое следующим текстом:
<?xml version="1.0" encoding="UTF-8"?><android.inputmethodservice.KeyboardView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/keyboard" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:keyPreviewLayout ="@layout/preview"/>
KeyPreviewLayout
- это макет недолговечного всплывающего окна, которое появляется при каждом нажатии клавиши на клавиатуре. Он содержит единственный TextView
. Создайте файл res/layout/preview.xml и добавьте к нему следующее:
<?xml version="1.0" encoding="utf-8"?><TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:background="#ffff00" android:textStyle="bold" android:textSize="30sp" > </TextView>
6. Определите клавиши клавиатуры
Детали клавиш клавиатуры и их позиции указаны в файле XML. Каждый ключ имеет следующие атрибуты:
-
keyLabel
: этот атрибут содержит текст, отображаемый на клавише. -
codes
: Этот атрибут содержит значения unicode символов, которые представляет ключ.
Например, чтобы определить ключ для буквы A, атрибут codes
должен иметь значение 97, а атрибут keyLabel
должен быть установлен в A.
Если с ключом связано несколько кодов, тогда символ, который представляет собой ключ, будет зависеть от количества нажатий, которые получает ключ. Например, если ключ имеет коды 63, 33 и 58:
- одно нажатие на клавишу приводит к символу «?»
- два быстрых нажатия приводят к символу «!»
- три отображают символ «:»
Ключ может также иметь несколько необязательных атрибутов:
-
keyEdgeFlags
: этот атрибут может принимать значениеleft
илиright
. Этот атрибут обычно добавляется к крайним левым и правым клавишам в строке. -
keyWidth
: этот атрибут определяет ширину клавиши. Обычно это определяется в виде процентного значения. -
isRepeatable
: если для этого атрибута установлено значениеtrue
, длительное нажатие клавиши будет повторять действие клавиши несколько раз. Обычно значениеtrue
установлено для клавиш удаления и пробела.
Клавиши клавиатуры сгруппированы в виде строк. Рекомендуется ограничить количество клавиш в строке до десяти, причем каждая клавиша имеет ширину, равную 10% от клавиатуры. В этом уроке высота клавиш установлена в 60dp. Это значение можно отрегулировать, но значения менее 48dp не рекомендуются. У нашей клавиатуры будет пять рядов ключей.
Теперь мы можем идти вперед и разрабатывать клавиатуру. Создайте новый файл с именем res/xml/qwerty.xml и замените его содержимое следующим текстом:
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android" android:keyWidth="10%p"android:horizontalGap="0px"android:verticalGap="0px"android:keyHeight="60dp"><Row><Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left"/><Key android:codes="50" android:keyLabel="2"/><Key android:codes="51" android:keyLabel="3"/><Key android:codes="52" android:keyLabel="4"/><Key android:codes="53" android:keyLabel="5"/><Key android:codes="54" android:keyLabel="6"/><Key android:codes="55" android:keyLabel="7"/><Key android:codes="56" android:keyLabel="8"/><Key android:codes="57" android:keyLabel="9"/><Key android:codes="48" android:keyLabel="0" android:keyEdgeFlags="right"/></Row><Row><Key android:codes="113" android:keyLabel="q" android:keyEdgeFlags="left"/><Key android:codes="119" android:keyLabel="w"/><Key android:codes="101" android:keyLabel="e"/><Key android:codes="114" android:keyLabel="r"/><Key android:codes="116" android:keyLabel="t"/><Key android:codes="121" android:keyLabel="y"/><Key android:codes="117" android:keyLabel="u"/><Key android:codes="105" android:keyLabel="i"/><Key android:codes="111" android:keyLabel="o"/><Key android:codes="112" android:keyLabel="p" android:keyEdgeFlags="right"/></Row><Row><Key android:codes="97" android:keyLabel="a" android:keyEdgeFlags="left"/><Key android:codes="115" android:keyLabel="s"/><Key android:codes="100" android:keyLabel="d"/><Key android:codes="102" android:keyLabel="f"/><Key android:codes="103" android:keyLabel="g"/><Key android:codes="104" android:keyLabel="h"/><Key android:codes="106" android:keyLabel="j"/><Key android:codes="107" android:keyLabel="k"/><Key android:codes="108" android:keyLabel="l"/><Key android:codes="35,64" android:keyLabel="\# \@" android:keyEdgeFlags="right"/></Row><Row> <Key android:codes="-1" android:keyLabel="CAPS" android:keyEdgeFlags="left"/><Key android:codes="122" android:keyLabel="z"/><Key android:codes="120" android:keyLabel="x"/><Key android:codes="99" android:keyLabel="c"/><Key android:codes="118" android:keyLabel="v"/><Key android:codes="98" android:keyLabel="b"/><Key android:codes="110" android:keyLabel="n"/><Key android:codes="109" android:keyLabel="m"/><Key android:codes="46" android:keyLabel="."/><Key android:codes="63,33,58" android:keyLabel="\? ! :" android:keyEdgeFlags="right"/></Row><Row android:rowEdgeFlags="bottom"> <Key android:codes="44" android:keyLabel="," android:keyWidth="10%p" android:keyEdgeFlags="left"/><Key android:codes="47" android:keyLabel="/" android:keyWidth="10%p" /><Key android:codes="32" android:keyLabel="SPACE" android:keyWidth="40%p" android:isRepeatable="true"/><Key android:codes="-5" android:keyLabel="DEL" android:keyWidth="20%p" android:isRepeatable="true"/><Key android:codes="-4" android:keyLabel="DONE" android:keyWidth="20%p" android:keyEdgeFlags="right"/></Row></Keyboard>
Возможно, вы заметили, что некоторые ключи имеют отрицательные значения в атрибуте codes
. Отрицательные значения равны предопределенным константам для класса Keyboard
. Например, значение -5
равно значению Keyboard.KEYCODE_DELETE
.
7. Создание класса Service
Создайте новый класс Java и назовите его SimpleIME.java. InputMethodService
и реализовать интерфейс OnKeyboardActionListener
. Интерфейс OnKeyboardActionListener
содержит методы, вызываемые при касании или нажатии клавиш экранной клавиатуры.
Класс SimpleIME
должен иметь три переменные-члена:
KeyboardView
, ссылающийся на представление, определенное в макете- Экземпляр
Keyboard
, который назначен дляKeyboardView
boolean
, сообщает нам включен ли caps lock
После объявления этих переменных и добавления методов интерфейса OnKeyboardActionListener
класс SimpleIME
должен выглядеть следующим образом:
public class SimpleIME extends InputMethodService implements OnKeyboardActionListener{private KeyboardView kv;private Keyboard keyboard;private boolean caps = false;@Overridepublic void onKey(int primaryCode, int[] keyCodes) {}@Overridepublic void onPress(int primaryCode) {}@Overridepublic void onRelease(int primaryCode) { }@Overridepublic void onText(CharSequence text) {}@Overridepublic void swipeDown() {}@Overridepublic void swipeLeft() {}@Overridepublic void swipeRight() {}@Overridepublic void swipeUp() {}}
Когда клавиатура создана, вызывается метод onCreateInputViewmethod
. Здесь могут быть инициализированы все переменные Service
. Обновите реализацию метода onCreateInputView
, как показано ниже:
@Overridepublic View onCreateInputView() {kv = (KeyboardView)getLayoutInflater().inflate(R.layout.keyboard, null);keyboard = new Keyboard(this, R.xml.qwerty);kv.setKeyboard(keyboard);kv.setOnKeyboardActionListener(this);return kv;}
Затем мы создаем метод, который воспроизводит звук при нажатии клавиши. Мы используем класс AudioManager
для воспроизведения звука. Android SDK включает в себя несколько стандартных звуковых эффектов по умолчанию для нажатия клавиш, и они используются в методе playClick
.
private void playClick(int keyCode){AudioManager am = (AudioManager)getSystemService(AUDIO_SERVICE);switch(keyCode){case 32: am.playSoundEffect(AudioManager.FX_KEYPRESS_SPACEBAR);break;case Keyboard.KEYCODE_DONE:case 10: am.playSoundEffect(AudioManager.FX_KEYPRESS_RETURN);break;case Keyboard.KEYCODE_DELETE:am.playSoundEffect(AudioManager.FX_KEYPRESS_DELETE);break;default: am.playSoundEffect(AudioManager.FX_KEYPRESS_STANDARD);}}
Наконец, обновите метод onKey
, чтобы наше приложение могло взаимодействовать с полями ввода (как правило, EditText
) других приложений.
Метод getCurrentInputConnection
используется для получения соединения с полем ввода другого приложения. После подключения мы можем использовать следующие методы:
-
commitText
для добавления одного или нескольких символов в поле ввода -
deleteSurroundingText
для удаления одного или нескольких символов поля ввода -
sendKeyEvent
для отправки событий, таких какKEYCODE_ENTER
, во внешнее приложение
Всякий раз, когда пользователь нажимает клавишу на клавиатуре, onKey
вызывается с использованием значения unicode ключа в качестве одного из его параметров. Основываясь на этом значении, клавиатура выполняет одно из следующих действий:
- В случае, если код следующий -
KEYCODE_DELETE
, то один символ слева от курсора удаляется с помощью методаdeleteSurroundingText
. - В случае, Если код -
KEYCODE_DONE
, событие ключаKEYCODE_ENTER
запускается. - В случае, Если код -
KEYCODE_SHIFT
, значениеcaps
изменяется, а состояние нажатия клавиатуры обновляется с помощью методаsetShifted
. При изменении состояния нажатия клавиши должны быть перерисованы, чтобы надписи клавиш были обновлены.InvalidateAllKeys
используется для перерисовки всех ключей. - Для всех других кодов код просто преобразуется в символ и отправляется в поле ввода. Если код представляет букву алфавита, а переменная
caps
имеет значениеtrue
, то символ преобразуется в верхний регистр.
Обновите метод onKey
, чтобы он выглядел так:
@Overridepublic void onKey(int primaryCode, int[] keyCodes) { InputConnection ic = getCurrentInputConnection(); playClick(primaryCode); switch(primaryCode){ case Keyboard.KEYCODE_DELETE : ic.deleteSurroundingText(1, 0); break; case Keyboard.KEYCODE_SHIFT: caps = !caps; keyboard.setShifted(caps); kv.invalidateAllKeys(); break; case Keyboard.KEYCODE_DONE: ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER)); break; default: char code = (char)primaryCode; if(Character.isLetter(code) && caps){ code = Character.toUpperCase(code); } ic.commitText(String.valueOf(code),1); }}
8. Тестирование клавиатуры
Итак, экранная клавиатура готова к тестированию. Скомпилируйте и запустите её на устройстве Android. Это приложение не имеет Activity
, что означает, что оно не появится в панели запуска. Чтобы использовать её, его следует сначала активировать в настройках устройства.
После активации Simple IME откройте любое приложение, которое позволяет вводить текст (например, любое приложение для обмена сообщениями) и понажимайте по одному из его полей ввода. Вы должны увидеть значок клавиатуры в области уведомлений. В зависимости от вашего устройства вы можете щелкнуть по этому значку или перетащить панель уведомлений вниз и выбрать Simple IME в качестве метода ввода. Теперь вы можете использовать новую клавиатуру.
Заключение
В этом уроке вы научились создавать клавиатуру для Android с нуля. Чтобы изменить внешний вид вашей клавиатуры, все, что вам нужно сделать, это добавить дополнительный стиль в файлы theres / layout / keyboard.xml и res / layout / preview.xml. Чтобы изменить положение клавиш, обновите файл res / xml / qwerty.xml. Чтобы добавить дополнительные функции на клавиатуру, обратитесь к документации разработчика.