Створення користувачем клавіатури на Android
Ukrainian (українська мова) translation by Elen (you can also view the original English article)



Більшість пристроїв андроїд не мають клавіатури. Вони покладаються на віртуальну або екранну клавіатуру для введення тексту користувачем. Якщо ви захоплюєтеся персоналізацією Android-пристроїв, знання, як користувач може створити екранну клавіатуру, можуть підняти ваше хобі на абсолютно новий рівень.
Використовуючи Android SDK, ви можете швидко створити екранну клавіатуру за допомогою на диво невеликої кількості рядків коду, тому що SDK виконує безліч задач простого рівня, таких як розпізнавання доторку до клавіші, малювання клавіатури та встановлення зв’язків між клавіатурою та полями введення.
В цьому уроці ви дізнаєтесь, як створити повнофункціональну екранну клавіатуру, яка слугуватиме вам в якості клавіатури Android по замовчуванню.
1. Необхідні вимоги.
Вам потрібно буде встановити Eclipse ADT Bundle. Ви можете завантажити його на сайті Android Developer.
2. Створіть новий проект.
Запустіть програму Eclipse та створіть новий додаток для Android. Назвіть додаток SimpleKeyboard. Переконайтесь, що ви обрали унікальне ім’я пакета. Встановіть мінімальну необхідну версію SDK – Android 2.2 та встановіть бажаний SDK – Android 4.4.



Даний додаток не матиме ніяких дій, тому зніміть галочку з Create Activity та натисніть Finish.



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



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



Закінчення
В даному уроці ви навчились створювати власну клавіатуру з нуля. Щоб змінити вигляд вашої клавіатури, вам потрібно внести додаткові зміни щодо стилю в файл res/layout/keyboard.xml і res/layout/preview.xml. Щоб змінити розміщення клавіш, обновіть файл res/xml/qwerty.xml. Щоб додати до вашої клавіатури більше функцій, поцікавтесь документацією розробника.



