📜 ⬆️ ⬇️

How to write your keyboard for Android

Hello. In this article I will try to tell and show the main points of writing your own keyboard for Android. The article is intended for developers who have not encountered this, but have experience exploring Android.

At once I will make a reservation that the author’s opinion and code are not the last resort, and your suggestions and criticisms are welcome. And if you do not want to read everything, link to the source at the end of the article.

First you need to create an empty Android project without an Activity. After that, let's proceed to the preparation of .xml files that will describe our keyboard to Android.

Basic layout file, keyboard.xml
')
It contains the View Android class called KeyboardView and describes the appearance of the keyboard.

<?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:keyPreviewHeight="35dp" android:keyPreviewLayout="@layout/preview" /> 

Attributes:


Preview code:

 <?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="@color/key_preview_background" android:textColor="@color/key_preview_text_color" android:textStyle="bold" android:textSize="25sp" /> 

An important point is that the background attribute is mandatory; if you do not specify it, then each time you press a key, your keyboard will fall.

Layout Description

So, we have prepared a 2 .xml file that describes the appearance, now it is the turn to describe the keyboard layout itself. Let's call this file keys_definition_ru.xml and it will be in the xml resources of the project. Here will be presented only his piece, since the file is quite large.

 <?xml version="1.0" encoding="utf-8"?> <Keyboard xmlns:android="http://schemas.android.com/apk/res/android" android:keyWidth="7.5%p" android:horizontalGap="5px" android:verticalGap="0px" android:keyHeight="40dp"> <Row> <Key android:codes="-1" android:keyIcon="@drawable/ic_keyboard_capslock_white_24dp" android:keyWidth="13%p" android:keyEdgeFlags="left" /> <Key android:codes="1103" android:keyLabel="" /> <Key android:codes="1095" android:keyLabel="" /> <Key android:codes="1089" android:keyLabel="" /> <Key android:codes="1084" android:keyLabel="" /> <Key android:codes="1080" android:keyLabel="" /> <Key android:codes="1090" android:keyLabel="" /> <Key android:codes="1100" android:keyLabel="" /> <Key android:codes="1073" android:keyLabel="" /> <Key android:codes="1102" android:keyLabel="" /> <Key android:codes="-5" android:keyIcon="@drawable/ic_backspace_white_24dp" android:isRepeatable="true" android:keyEdgeFlags="right" android:keyWidth="13%p" /> </Row> </Keyboard> 

Attributes:

All attributes will not be described, only "not obvious."


The final file is a description of localization (input subtypes):

 <?xml version="1.0" encoding="utf-8"?> <input-method xmlns:android="http://schemas.android.com/apk/res/android"> <subtype android:label="@string/subtype_en_US" android:imeSubtypeLocale="en_US" android:imeSubtypeMode="keyboard" /> <subtype android:label="@string/subtype_ru_RU" android:imeSubtypeLocale="ru_RU" android:imeSubtypeMode="keyboard" /> </input-method> 

InputMethodService - keyboard service

Now, after we have created all the necessary xml files, we proceed to the description of the service that will listen for the InputMethod events.

To do this, create a service, inheriting from InputMethodService and immediately implement the KeyboardView.OnKeyboardActionListener interface. As a result, you get a set of methods that you can override and fill with the necessary functionality that allows you to widely customize your keyboard. But here I will give only examples of basic points.

OnCreateInputView and onKey methods
  @Override public View onCreateInputView() { mKeyboardView = (KeyboardView) getLayoutInflater().inflate(R.layout.keyboard, null); mKeyboard = new Keyboard(this, R.xml.keys_definition_ru); mKeyboard.setShifted(isCapsOn); //    ,     mKeyboardView.setKeyboard(mKeyboard); mKeyboardView.setOnKeyboardActionListener(this); return mKeyboardView; } @Override public void onKey(int primaryCode, int[] ints) { Log.d(TAG, "onKey " + primaryCode); InputConnection ic = getCurrentInputConnection(); playClick(primaryCode); switch (primaryCode) { case Keyboard.KEYCODE_DELETE: ic.deleteSurroundingText(1, 0); break; case Keyboard.KEYCODE_SHIFT: handleShift(); break; case Keyboard.KEYCODE_DONE: ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER)); break; case Keyboard.KEYCODE_ALT: handleSymbolsSwitch(); break; case Keyboard.KEYCODE_MODE_CHANGE: handleLanguageSwitch(); break; default: char code = (char) primaryCode; if (Character.isLetter(code) && isCapsOn) { code = Character.toUpperCase(code); } ic.commitText(String.valueOf(code), 1); break; } } 


One of the methods of the InputMethodService life cycle is onCreateInputView, inside which we create the Keyboard View and bind the necessary listeners to it.

The onKey event is triggered between onPress and onRelease, the input is the code of the pressed key.

So, everything is ready ... almost, it remains to add our service to the manifest.

 <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> 

Congratulations, you wrote your first keyboard!

Keyboard source code (caps is on by default)
Official documentation / tutorial

Source: https://habr.com/ru/post/322070/


All Articles