CustomKeyboardEngine is a flexible and customizable keyboard engine for Android.
- Multiple Layout Support: Language layouts and service layouts are dynamically loaded from files.
- Customizable JSON-Based Layouts: Define rows, keys, dimensions, and behavior using JSON.
- Dynamic Reloading: Layouts can be reloaded when files change.
- Modifier and Sticky Keys: Support for Shift, Ctrl, Alt, and Caps Lock behavior.
- Floating Keyboard: Optional floating keyboard mode for overlay input.
- Error Notifications: Parsing errors are shown in popups for debugging.
Andorid/media/com.roalyr.customkeyboardengine
├── layouts/
│ ├── layouts-language/ # Language-specific layouts
│ │ ├── keyboard-default.json
│ │ ├── keyboard-default-ua.json
│ │ └── ... (other layouts)
│ ├── layouts-service/ # Service-specific layouts
│ │ ├── keyboard-service.json
└── ...
The root object of the layout file.
Attribute | Type | Description |
---|---|---|
rows |
List | List of rows that contain the keyboard keys. |
defaultKeyHeight |
Float | Default key height (in DP). |
defaultKeyWidth |
Float | Default key width (percentage of row width). |
defaultRowGap |
Float | Default gap between rows (in DP). |
defaultKeyGap |
Float | Default gap between keys (percentage or DP). |
Defines a row in the keyboard.
Attribute | Type | Description |
---|---|---|
keys |
List | List of keys in this row. |
rowHeight |
Float? | Height of the row (fallback to defaultKeyHeight ). |
rowGap |
Float? | Space below this row. |
defaultKeyWidth |
Float? | Default width for keys in this row. |
defaultKeyGap |
Float? | Default gap for keys in this row. |
Defines individual key attributes.
Attribute | Type | Description |
---|---|---|
keyCode |
Int | Primary key code. |
keyCodeLongPress |
Int? | Key code triggered on long press. |
isRepeatable |
Boolean | If true, the key repeats when held. |
isModifier |
Boolean | If true, the key acts as a modifier (Shift, Ctrl). |
isSticky |
Boolean | If true, the key toggles its state (e.g., Caps). |
label |
String? | Primary text label on the key. |
smallLabel |
String? | Small secondary label. |
icon |
String? | Path to the key's drawable icon (e.g., "@drawable/icon_name"). |
keyWidth |
Float? | Width of the key (fallback to row or layout defaults). |
keyHeight |
Float? | Height of the key (fallback to row defaults). |
keyGap |
Float? | Gap to the next key. |
x |
Float | Logical X position (calculated automatically). |
y |
Float | Logical Y position (calculated automatically). |
Custom keycodes are used to trigger special actions. These are defined in the Constants.kt
file:
Keycode | Value | Description |
---|---|---|
KEYCODE_CLOSE_FLOATING_KEYBOARD |
-10 | Closes the floating keyboard. |
KEYCODE_OPEN_FLOATING_KEYBOARD |
-11 | Opens the floating keyboard. |
KEYCODE_SWITCH_KEYBOARD_MODE |
-12 | Switches the keyboard mode. |
KEYCODE_ENLARGE_FLOATING_KEYBOARD |
-13 | Enlarges the floating keyboard horizontally. |
KEYCODE_SHRINK_FLOATING_KEYBOARD |
-14 | Shrinks the floating keyboard horizontally. |
KEYCODE_ENLARGE_FLOATING_KEYBOARD_VERT |
-15 | Enlarges the floating keyboard vertically. (TODO) |
KEYCODE_SHRINK_FLOATING_KEYBOARD_VERT |
-16 | Shrinks the floating keyboard vertically. (TODO) |
KEYCODE_MOVE_FLOATING_KEYBOARD_LEFT |
-17 | Moves the floating keyboard to the left. |
KEYCODE_MOVE_FLOATING_KEYBOARD_RIGHT |
-18 | Moves the floating keyboard to the right. |
KEYCODE_MOVE_FLOATING_KEYBOARD_UP |
-19 | Moves the floating keyboard upward. |
KEYCODE_MOVE_FLOATING_KEYBOARD_DOWN |
-20 | Moves the floating keyboard downward. |
KEYCODE_CYCLE_LANGUAGE_LAYOUT |
-21 | Cycles through available language layouts. |
KEYCODE_IGNORE |
-1 | Placeholder. |
For all other standard keycodes, refer to Android KeyEvent Documentation.
Layouts are dynamically reloaded when initiating an input view or cycling layouts:
- Language Layouts are loaded from
layouts-language/
. - Service Layouts are loaded from
layouts-service/
.
Upon every launch, the app copies default layouts into the following folders if they are missing:
layouts-language/keyboard-default.json
layouts-service/keyboard-service.json
If these files are missing or corrupted, fallback layouts are loaded from built-in resources. You can use those layouts as templates by saving them under different names.
- Place Layout Files: Add your JSON files to
layouts-language/
orlayouts-service/
. (TODO: implement custom keycodes for service keyboards). - Edit Layouts: Customize keys, dimensions, and behaviors in the JSON files.
- Restart Keyboard: The keyboard detects changes and reloads layouts dynamically.
- Switch Layouts: Use the
KEYCODE_CYCLE_LANGUAGE_LAYOUT
key to cycle through language layouts.
- Modifier keys (Shift, Ctrl, Alt) automatically update key labels to reflect their state.
- Caps Lock toggles its state on press.
- Long-press actions can be defined using
keyCodeLongPress
orsmallLabel
. - Keys can extend into adjacent rows using custom heights (like a space key in default layout).
- Parsing errors are displayed as error popups on the screen with details.
- Every error is also mirrored via
Log.e()
call. Log.i()
,Log.d()
are (should be) suppressed, leaving no trace of app activity.
-
Issue: Layouts are not updating.
Solution: Check for syntax errors in the JSON files. Ensure correct file placement. -
Issue: Keyboard doesn't show.
Solution: Verify overlay and storage permissions are granted. -
Issue: Keyboard crashes when loading a layout.
Solution: Check the error popups or logs for parsing issues and fix the JSON structure.