I've followed the examples on developer.android.com regarding Input Methods and played with the SoftKeyboard sample application. These together give more than enough information regarding the creation of simple keyboard.
What I can't see in the API is the ability to create alternate / multiple characters per key which is available on the standard Keyboard (LatinIME Keyboard).
The above image is the result of a long press on the "a" key. When you long press a key it's possible to populate a popup with alternate characters.
It is also possible to give a popup hint on some keys which will prompt the user to press and hold a key in order to get the popup menu.
So far I haven't found a single source of information on how this is achieved, hopefully someone will be able to give me a head start, until then I'll follow the source code of the inbuilt keyboard and see if I can reverse engineer it.
Edit: Would help if developer.android.com 's link to the LatinIME Keyboard didn't link to a picture of a Sheep :) Actual source code for LatinIME.java.
Edit 2: More as a reference than anything else, this is the sequence I believe a usual longPress action goes through in order to show the popup keyboard in KeyboardView.java:
onTouchEvent()
onModifiedTouchEvent()
mHandkler.handleMessage() with MSG_LONGPRESS
openPopupIfRequired()
onLongPress()
Edit 3:
I still haven't figured this out - How do you add label suggestions to keys? An answer suggests it isn't built into the API and indeed I haven't found the codeto do this. However the Keyboard on 2.3.4 (API 10) shows this functionality being implemented:
Would very much like to figure out how IT does it but it isn't anywhere in the onDraw()
method that I can see - which makes me believe it's being written outside of the KeyboardView element. I can't however find the layout
file used to display the KeyboardView element on the inbuilt keyboard - If anyone knows where to find this perhaps that will give me the clue I need.
Edit 4: Moved key Preview question here as it's slightly off topic:
Judging from my own attempt at coding a softkeyboard I found out that:
KeyboardView
and basically write large parts of the drawing code. Unfortunately you cannot do this by overriding some key methods since almost everything is private. You might want to take a look (and borrow some code from:(base)/core/java/android/inputmethodservice/KeyboardView.java
(android core code repo)(apps)/other/LatinIME/LatinKeyboardView.java
(android core apps repo)Note that the sheep on android.kernel.org is there to tell you that the repo is closed due to crackers but there are mirrors of the code elsewhere (lost the links unfortunately)
KeyboardView
has no support for shadowed key hints, you must code your own KeyboardView to get a chance to override the onDraw() method.Now on what you can do:
You can workaround this issue by providing pictures for the keys: use xml
<Key ... android:keyIcon="@drawable/this_key_icon_file />
for this. Unfortunately, you'll most certainly have poor results for letters with this method (resolution issues).You can use (and configure appearance of) popup keyboard that appears on long press.
Declare a keyboard template
res/xml/kbd_popup_template.xml
:Declare string values containing the keys you want on this keyboard
res/values/strings.xml
:Then, use both in your keyboard layout definition:
You can also use double-tap, triple-tap, ... feature to generate alternates for the key you're tapping. To do so, simply use a list for the android keycodes:
<Key android:codes="97,224,230" .../>
will produce 97='
a
' for single tap, 224='à
' for double-tap and 230='æ
' for triple-tap.The duration to consider double-tapping is set to 800ms in android source code. It's unfortunately hardcoded (and a bit high, I feel).
Be aware that, when double-tapping, it basically sends an '
a
' first, then, on the second tap it sends 'à
'. Some apps, will not like this.That popup keyboard with the close button is annoying when we have only one popup character. Simpler way is to override the onLongPress method of KeyboardView class like this.
Implementing alternate key popup:
For each key you wish to have a popup keyboard you should define popupCharacters and popupKeyboard:
/res/xml/[Keyboard].xml
The
popupKeyboard
is an XML representation of the keyboard used in the popup containing the alternate keys:/res/xml/keyboard_popup_template.xml
Styling the alternate key popup:
If you want to change the layout/style of the popup (which defaults to @android:layout/ keyboard_popup_keyboard.xml) you can specify a
android:popupLayout
attribute which points to a layout file:Implementing Key Preview Overlay:
The only solution I've been able to knock together to show key previews (Without entirely rewriting the KeyboardView source code) is below:
Wrapping the
<KeyboardView>
tag with a<FrameLayout>
with a height specified by multiplying the keyHeight by the amount of rows. Inside this tag I've simply created a LinearLayout to hold rows, then a LinearLayout for each row containing a TextView with a weight equal to the %p value specified for each<Key>
:And styled:
Which produces this:
I won't be happy until I've managed to implement this in the same way as the System Keyboard does!
If you want to have a text on top of your key, you can do it in onDraw() method in your class that overrides KeyboardView
For anyone trying to dismiss the popup keyboard by tapping outside its view area, I've had some luck putting a
TouchListener
on theKeyboardView
inside the class extendingInputMethodService
if you want to have a text on top of your key, you can do it in onDraw() method in your class that extends KeyboardView i did something like this maybe this could help someone
adjust these axis according to your choice