Статьи

Создать пользовательскую клавиатуру на Android

Конечный продукт
Что вы будете создавать

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

Используя Android SDK, вы можете быстро создать программную клавиатуру с удивительно небольшим количеством строк кода, потому что SDK выполняет множество задач низкого уровня, таких как распознавание касаний клавиш, рисование клавиатуры и установление соединений между клавиатурой и поля ввода.

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

Если вы спешите, посмотрите Android Keyboard Themes , готовое к использованию решение от Envato Market.

Приложение дает вам возможность выбрать одну из 22 встроенных тем клавиатуры или создать собственную тему.

Темы клавиатуры Android
Темы клавиатуры Android

Или вы можете нанять фрилансера в Envato Studio. Просто просмотрите наш раздел Mobile & Apps, и вы обязательно найдете эксперта, который сможет вам помочь.

Разработчики мобильных приложений и приложений на Envato Studio
Разработчики мобильных приложений и приложений в Envato Studio

Если вы предпочитаете создавать свои собственные, читайте дальше, чтобы узнать, как это сделать.

Вам понадобится Eclipse ADT Bundle. Вы можете скачать его с сайта разработчика Android .

Запустите Eclipse и создайте новое приложение для Android. Назовите это приложение, SimpleKeyboard . Убедитесь, что вы выбрали уникальное имя пакета. Установите минимально необходимый SDK для Android 2.2 и установите целевой SDK для Android 4.4 .

Это приложение не будет иметь никаких действий, поэтому снимите флажок Создать действие и нажмите Готово .

Программная клавиатура рассматривается в качестве редактора метода ввода (IME) операционной системой Android. IME объявляется как Service в AndroidManifest.xml, которая использует разрешение BIND_INPUT_METHOD и отвечает на действие android.view.InputMethod .

Добавьте следующие строки в тег application манифеста:

1
2
3
4
5
6
7
8
9
<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>

Тег service в файле манифеста содержит тег meta-data который ссылается на файл XML с именем method.xml . Без этого файла операционная система Android не распознает наш Service как действительный сервис IME. Файл содержит сведения о методе ввода и его подтипах. Для нашей клавиатуры мы определяем один подтип для локали en_US . Создайте каталог res / xml, если он не существует, и добавьте в него файл method.xml . Содержимое файла должно быть:

1
2
3
4
5
6
7
<?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>

Строки, используемые этим приложением, определены в файле res / values ​​/ strings.xml . Нам понадобятся три строки:

  • название приложения
  • ярлык IME
  • метка подтипа IME

Обновите ваш strings.xml, чтобы он содержал следующее содержимое:

1
2
3
4
5
<resources>
    <string name=»app_name»>SimpleKeyboard</string>
    <string name=»simple_ime»>Simple IME</string>
    <string name=»subtype_en_US»>English (US)</string>
</resources>

Раскладка нашей клавиатуры содержит только KeyboardView . layout_alignParentBottom имеет значение true поэтому клавиатура отображается в нижней части экрана.

Создайте файл с именем res / layout / keyboard.xml и замените его содержимое следующим:

1
2
3
4
5
6
7
8
9
<?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 и добавьте в него следующее:

01
02
03
04
05
06
07
08
09
10
<?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>

Детали клавиш клавиатуры и их положения указаны в файле XML. Каждый ключ имеет следующие атрибуты:

  • keyLabel : этот атрибут содержит текст, отображаемый на ключе.
  • codes : этот атрибут содержит значения Unicode символов, которые представляет ключ.

Например, чтобы определить ключ для буквы A , атрибут codes должен иметь значение 97, а атрибут keyLabel должен быть установлен в A.

Если с ключом связано более одного кода, то символ, который представляет ключ, будет зависеть от количества нажатий, которые получает ключ. Например, если ключ имеет коды 63 , 33 и 58 :

  • одно нажатие на клавишу приводит к персонажу ?
  • два нажатия в быстрой последовательности приводит к характеру !
  • три нажатия в быстрой последовательности приводит к персонажу :

Ключ также может иметь несколько необязательных атрибутов:

  • keyEdgeFlags : этот атрибут может принимать значение left или right . Этот атрибут обычно добавляется к крайним левым и правым клавишам строки.
  • keyWidth : этот атрибут определяет ширину ключа. Обычно это определяется как процентное значение.
  • isRepeatable : если для этого атрибута установлено значение true , длительное нажатие клавиши будет повторять действие клавиши несколько раз. Обычно это значение true для клавиш удаления и пробела.

Клавиши клавиатуры сгруппированы как строки. Рекомендуется ограничить количество клавиш в строке максимум десятью, при этом ширина каждой клавиши равна 10% от клавиатуры. Высота клавиш в этом уроке установлена ​​на 60dp . Это значение можно отрегулировать, но значения менее 48 dp не рекомендуется. Наша клавиатура будет иметь пять рядов клавиш.

Теперь мы можем пойти дальше и разработать клавиатуру. Создайте новый файл с именем res / xml / qwerty.xml и замените его содержимое следующим:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<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 .

Создайте новый класс Java и назовите его SimpleIME.java . Класс должен расширять класс InputMethodService и реализовывать интерфейс OnKeyboardActionListener . Интерфейс OnKeyboardActionListener содержит методы, которые вызываются при нажатии или нажатии клавиш программной клавиатуры.

Класс SimpleIME должен иметь три переменные-члены:

  • KeyboardView ссылающийся на вид, определенный в макете
  • Экземпляр Keyboard который назначен для KeyboardView
  • boolean сообщающее нам, включена ли блокировка заглавных букв

После объявления этих переменных и добавления методов интерфейса SimpleIME класс SimpleIME должен выглядеть следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class SimpleIME extends InputMethodService
    implements OnKeyboardActionListener{
     
    private KeyboardView kv;
    private Keyboard keyboard;
     
    private boolean caps = false;
 
    @Override
    public void onKey(int primaryCode, int[] keyCodes) {
 
    }
 
    @Override
    public void onPress(int primaryCode) {
    }
 
    @Override
    public void onRelease(int primaryCode) {
    }
 
    @Override
    public void onText(CharSequence text) {
    }
 
    @Override
    public void swipeDown() {
    }
 
    @Override
    public void swipeLeft() {
    }
 
    @Override
    public void swipeRight() {
    }
 
    @Override
    public void swipeUp() {
    }
}

Когда клавиатура создана, onCreateInputView метод onCreateInputView . Все переменные-члены Service могут быть инициализированы здесь. Обновите реализацию метода onCreateInputView как показано ниже:

1
2
3
4
5
6
7
8
@Override
public 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 .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
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 метод onKey со значением onKey клавиши в качестве одного из ее параметров. На основе этого значения клавиатура выполняет одно из следующих действий:

  • Если код KEYCODE_DELETE , один символ слева от курсора удаляется с deleteSurroundingText метода deleteSurroundingText .
  • Если код KEYCODE_DONE , KEYCODE_ENTER событие ключа KEYCODE_ENTER .
  • Если код KEYCODE_SHIFT , значение переменной caps изменяется, а состояние сдвига клавиатуры обновляется с setShifted метода setShifted . Клавиатуру необходимо перерисовывать при изменении состояния, чтобы метки клавиш обновлялись. Метод invalidateAllKeys используется для перерисовки всех ключей.
  • Для всех остальных кодов код просто преобразуется в символ и отправляется в поле ввода. Если код представляет букву алфавита, а переменная caps установлена ​​в значение true , то символ преобразуется в верхний регистр.

Обновите метод onKey чтобы он выглядел так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Override
public 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);
    }
}

Программная клавиатура готова к тестированию. Скомпилируйте и запустите его на устройстве Android. Это приложение не имеет Activity , что означает, что оно не будет отображаться в панели запуска. Чтобы его использовать, его сначала нужно активировать в настройках устройства.

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

Из этого урока вы узнали, как создать собственное приложение для клавиатуры с нуля. Чтобы изменить внешний вид вашей клавиатуры, все, что вам нужно сделать, это добавить дополнительные стили к файлам res / layout / keyboard.xml и res / layout / preview.xml . Чтобы изменить положения ключей, обновите файл res / xml / qwerty.xml . Чтобы добавить больше функций к вашей клавиатуре, обратитесь к документации разработчика .