# How to Add QWERTY Layout Support Alongside the Traditional Japanese Flick Layout

> Easily add QWERTY layout support to the Japanese Keyboard project. Learn how to enable the toggle, instantiate the view, and wire the layout switch for seamless flick and QWERTY mode switching.

- Repository: [Kazu/japanesekeyboard](https://github.com/kazumaproject/japanesekeyboard)
- Tags: how-to-guide
- Published: 2026-03-05

---

**You can add QWERTY layout support to the Japanese Keyboard project by enabling the QWERTY preference toggle, instantiating the QWERTY view in the KeyboardViewPagerAdapter, and wiring the layout switch in IMEService to toggle between FlickKeyboardView and QWERTYKeyboardView based on the QWERTYMode state flow.**

The kazumaproject/japanesekeyboard repository provides a flexible Android IME framework that supports both traditional Japanese flick input and standard QWERTY layouts. If you want to add QWERTY layout support alongside the traditional Japanese flick layout, the codebase already contains the necessary components—you only need to connect the preference toggle, view instantiation, and mode switching logic.

## Step 1: Enable the QWERTY Preference

The first step is to surface the QWERTY option to users via the settings UI. The file [`app/src/main/res/xml/pref_qwerty.xml`](https://github.com/kazumaproject/japanesekeyboard/blob/main/app/src/main/res/xml/pref_qwerty.xml) defines the toggle switches that control QWERTY behavior, including options for enabling up and down flick detection on the QWERTY keys.

When a user toggles these preferences, the changes propagate through the settings fragment and update the keyboard view state. Ensure this preference XML is included in your main settings hierarchy so users can access the QWERTY configuration panel.

## Step 2: Instantiate the QWERTY View

Once the preference is enabled, you must ensure the QWERTY keyboard view is available for display. The `KeyboardViewPagerAdapter` located at [`app/src/main/java/com/kazumaproject/markdownhelperkeyboard/setting_activity/ui/keyboard_size_setting/adapter/KeyboardViewPagerAdapter.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/app/src/main/java/com/kazumaproject/markdownhelperkeyboard/setting_activity/ui/keyboard_size_setting/adapter/KeyboardViewPagerAdapter.kt) manages three distinct pages: Ten-Key (Japanese), QWERTY, and Custom.

The adapter creates the appropriate view based on position constants (`TEN_KEY_PAGE_POSITION`, `QWERTY_PAGE_POSITION`). To add QWERTY support, verify that the adapter returns a non-null `QWERTYKeyboardView` for the QWERTY page position. This view is instantiated using the application context and configured with the appropriate layout and listeners.

## Step 3: Wire the Layout Switch

The core switching logic resides in the IME service. The [`IMEService.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/IMEService.kt) file at [`app/src/main/java/com/kazumaproject/markdownhelperkeyboard/ime_service/IMEService.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/app/src/main/java/com/kazumaproject/markdownhelperkeyboard/ime_service/IMEService.kt) observes a `StateFlow<QWERTYMode>` named `_qwertyMode` defined in [`core/src/main/java/com/kazumaproject/core/domain/state/QWERTYMode.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/core/src/main/java/com/kazumaproject/core/domain/state/QWERTYMode.kt).

The `QWERTYMode` enum includes states such as `Default`, `Romaji`, and `CapsLock`. When the user selects QWERTY from the settings or via a toggle, the service updates this flow, triggering a view replacement. The service removes the current `FlickKeyboardView` and attaches a `QWERTYKeyboardView`, preserving the `setOnKeyboardActionListener` interface so input handling remains consistent.

## Step 4: Provide a Default QWERTY Layout

To render keys on the QWERTY view, you must define the layout structure. The `KeyboardDefaultLayouts` object in [`custom_keyboard/src/main/java/com/kazumaproject/custom_keyboard/layout/KeyboardDefaultLayouts.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/custom_keyboard/src/main/java/com/kazumaproject/custom_keyboard/layout/KeyboardDefaultLayouts.kt) provides static definitions for Hiragana, English, and Symbol layouts.

You can add QWERTY support by extending this object with a Romaji layout method or by creating a new XML layout file. For XML-based layouts, inflate the resource inside `QWERTYKeyboardView` using view binding (`QwertyLayoutBinding`). For programmatic layouts, construct a `KeyboardLayout` data class with rows of `KeyInfo` objects and call `qwertyKeyboardView.setRomajiKeyboard(layout)`.

## Step 5: Customize QWERTY Appearance

Finally, allow users to fine-tune the QWERTY appearance through the settings UI. The [`QwertyMarginSettingFragment.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/QwertyMarginSettingFragment.kt) at [`app/src/main/java/com/kazumaproject/markdownhelperkeyboard/setting_activity/ui/qwerty_button_size/QwertyMarginSettingFragment.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/app/src/main/java/com/kazumaproject/markdownhelperkeyboard/setting_activity/ui/qwerty_button_size/QwertyMarginSettingFragment.kt) provides sliders and inputs for adjusting key margins and text size.

The [`QwertyKeyboardSizePreview.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/QwertyKeyboardSizePreview.kt) component renders a live preview of these changes. These UI components read from and write to the shared preferences, which the `QWERTYKeyboardView` observes to update its rendering dynamically.

## Code Examples

### Enabling the QWERTY Preference in Settings

```kotlin
// In SettingsFragment (or wherever you load preferences)
val qwertyEnableSwitch = findPreference<SwitchPreferenceCompat>("qwerty_enable_flick_up_preference")
qwertyEnableSwitch?.setOnPreferenceChangeListener { _, newValue ->
    // Persist the setting and notify the keyboard view
    qwertyKeyboardView.enableFlickUpDetection = newValue as Boolean
    true
}

```

### Switching to QWERTY from the IME Service

```kotlin
private fun switchToQwerty() {
    // Update the shared flow – observers in KeyboardViewPagerAdapter will react
    _qwertyMode.value = QWERTYMode.Romaji

    // Directly replace the view if you keep a reference
    val qwertyView = QWERTYKeyboardView(this)
    qwertyView.setOnKeyboardActionListener(qwertyListener)
    keyboardContainer.removeAllViews()
    keyboardContainer.addView(qwertyView)
}

```

### Adding a Custom QWERTY Layout in KeyboardDefaultLayouts.kt

```kotlin
fun defaultQwertyRomajiLayout(): KeyboardLayout {
    // Define rows of keys – each key is a `KeyInfo` that holds the label, code, etc.
    val rows = listOf(
        listOf(KeyInfo("Q", "q"), KeyInfo("W", "w"), /* … */ KeyInfo("P", "p")),
        listOf(KeyInfo("A", "a"), /* … */ KeyInfo("L", "l")),
        listOf(KeyInfo("Z", "z"), /* … */ KeyInfo("M", "m"))
    )
    // Convert rows into the library's `KeyboardLayout` data class
    return KeyboardLayout(rows.flatten(), emptyMap(), columns = 10, rows = 4)
}

```

Then load it:

```kotlin
qwertyKeyboardView.setRomajiKeyboard(
    KeyboardDefaultLayouts.defaultQwertyRomajiLayout()
)

```

### Updating the ViewPager Adapter

```kotlin
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    val binding = LayoutInflater.from(parent.context)
        .inflate(R.layout.qwerty_layout, parent, false)
    val qwertyView = QWERTYKeyboardView(parent.context)
    return ViewHolder(binding.apply { root.addView(qwertyView) })
}

```

## Summary

- **Enable the preference** by including [`pref_qwerty.xml`](https://github.com/kazumaproject/japanesekeyboard/blob/main/pref_qwerty.xml) in your settings to expose QWERTY toggles to users.
- **Instantiate the view** through `KeyboardViewPagerAdapter` to ensure the QWERTY page is available alongside the Ten-Key and Custom pages.
- **Wire the switch** in [`IMEService.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/IMEService.kt) by observing the `QWERTYMode` state flow and swapping between `FlickKeyboardView` and `QWERTYKeyboardView`.
- **Define the layout** by extending [`KeyboardDefaultLayouts.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/KeyboardDefaultLayouts.kt) with Romaji key definitions or by inflating a custom XML layout in `QWERTYKeyboardView`.
- **Customize appearance** via [`QwertyMarginSettingFragment.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/QwertyMarginSettingFragment.kt) to let users adjust key margins and text size for the QWERTY layout.

## Frequently Asked Questions

### What is the difference between FlickKeyboardView and QWERTYKeyboardView?

`FlickKeyboardView` implements the traditional Japanese flick behavior where users swipe in different directions to select characters, while `QWERTYKeyboardView` provides a standard QWERTY layout with dynamic margins, caps-lock handling, and optional up/down flick detection. Both extend `ConstraintLayout` and implement `setOnKeyboardActionListener`, allowing the IME service to treat them uniformly.

### How does the IME service know when to switch layouts?

The IME service observes a `StateFlow<QWERTYMode>` defined in [`core/src/main/java/com/kazumaproject/core/domain/state/QWERTYMode.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/core/src/main/java/com/kazumaproject/core/domain/state/QWERTYMode.kt). When the user selects QWERTY from settings or toggles the mode, the flow emits a new state (such as `Romaji` or `Default`), triggering [`IMEService.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/IMEService.kt) to replace the current `FlickKeyboardView` with a `QWERTYKeyboardView`.

### Can I customize the QWERTY key sizes and margins?

Yes, the [`QwertyMarginSettingFragment.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/QwertyMarginSettingFragment.kt) file provides a dedicated UI for adjusting QWERTY key margins and text size. These settings persist to shared preferences, which `QWERTYKeyboardView` reads to update its rendering dynamically. You can also programmatically set margins via the view's layout parameters if you need custom defaults.

### Is it possible to use both layouts simultaneously?

While users cannot physically display both keyboards at the same time in the same input field, the architecture supports rapid switching between them without restarting the IME. The `KeyboardViewPagerAdapter` holds both views in memory (Ten-Key, QWERTY, and Custom pages), and the IME service can instantly swap the active view based on the current `QWERTYMode`, effectively allowing simultaneous availability with zero-latency switching.