How to Configure Flick Sensitivity and Angle Ranges in JapaneseKeyboard

Configure flick sensitivity and angle ranges in JapaneseKeyboard by calling setFlickSensitivityValue() for pixel-threshold tuning and setAngleAndRange() for custom directional mappings.

The JapaneseKeyboard project provides granular control over flick gesture interpretation across all keyboard layouts, including TenKey, Tablet, and the custom circular-flick interface. By adjusting sensitivity thresholds and angular segment boundaries, developers can tailor the typing experience to specific device sizes, user dexterity levels, or custom design languages.

Understanding Flick Sensitivity

Flick sensitivity acts as a pixel-based threshold that determines whether a touch movement registers as a tap or a flick. The default value is 100 pixels, defined in each keyboard view implementation.

When the absolute distance of a touch move is less than the sensitivity value, the system interprets the gesture as a tap. Exceeding this threshold triggers flick detection logic.

Setting Sensitivity Programmatically

To configure sensitivity directly on a keyboard view instance, call setFlickSensitivityValue():

// FlickKeyboardView.kt, TabletKeyboardView.kt, or TenKey.kt
val keyboard = FlickKeyboardView(context)
keyboard.setFlickSensitivityValue(80)   // More sensitive (shorter swipes trigger flicks)
keyboard.setFlickSensitivityValue(150)  // Less sensitive (requires longer swipes)

The internal motion handling logic in FlickKeyboardView.kt (around line 1840) applies this threshold:

abs(distanceX) < flickSensitivity && abs(distanceY) < flickSensitivity -> GestureType.Tap

Reading from SharedPreferences

The production implementation reads user preferences from pref_custom.xml and applies them via IMEService.kt:

// IMEService.kt
keyboardView.setFlickSensitivityValue(flickSensitivityPreferenceValue ?: 100)
tabletView.setFlickSensitivityValue(flickSensitivityPreferenceValue ?: 100)
customLayoutDefault.setFlickSensitivityValue(flickSensitivityPreferenceValue ?: 100)

The preference key flickSensitivityPreferenceValue is defined in app/src/main/res/xml/pref_custom.xml.

Customizing Circular Flick Angle Ranges

For the circular-flick layout, the keyboard divides the popup into four directional segments: UP, DOWN, UP_RIGHT_FAR, and UP_LEFT_FAR. Each segment is defined by a start angle and sweep size in degrees.

Default Angle Configuration

When no custom ranges are provided, FlickKeyboardView.kt uses the following default map in the attachKeyBehavior block:

mapOf(
    FlickDirection.UP to Pair(225f, 90f),           // 225° to 315°
    FlickDirection.UP_RIGHT_FAR to Pair(315f, 90f), // 315° to 45° (wraps around)
    FlickDirection.DOWN to Pair(45f, 90f),           // 45° to 135°
    FlickDirection.UP_LEFT_FAR to Pair(135f, 90f)    // 135° to 225°
)

Defining Custom Ranges

To override the defaults programmatically, construct a Map<FlickDirection, Pair<Float, Float>> where each pair represents (startAngle, sweepAngle):

val customRanges = mapOf(
    FlickDirection.UP to Pair(210f, 80f),
    FlickDirection.UP_RIGHT_FAR to Pair(310f, 100f),
    FlickDirection.DOWN to Pair(30f, 80f),
    FlickDirection.UP_LEFT_FAR to Pair(130f, 80f)
)

val viewScale = 1.2f  // Makes the popup 20% larger
flickKeyboardView.setAngleAndRange(customRanges, viewScale)

The setAngleAndRange() method in FlickKeyboardView.kt stores these values in customAngleAndRange and passes them to CustomAngleFlickController for gesture calculation.

Applying Changes via Settings UI

The CircularFlickSettingsFragment.kt provides a user interface for adjusting angles visually. When the user modifies a segment, the fragment builds an angleData map and applies it to both the preview and the active keyboard:

// CircularFlickSettingsFragment.kt (simplified)
val ranges = angleData // Map<FlickDirection, Pair<Float, Float>>
binding.previewView.setRanges(ranges)          // Update preview only
keyboardView.setAngleAndRange(ranges, scale) // Update actual keyboard

Complete Configuration Pipeline

When the IME service initializes, it orchestrates both sensitivity and angle configurations through the following flow:

  1. Read Preferences: IMEService.kt retrieves flickSensitivityPreferenceValue from pref_custom.xml.
  2. Apply Sensitivity: The service calls setFlickSensitivityValue() on FlickKeyboardView, TabletKeyboardView, and TenKey instances.
  3. Apply Custom Angles: If the user previously configured custom circular-flick angles via CircularFlickSettingsFragment, those values are loaded and applied through setAngleAndRange().
  4. Runtime Updates: Both settings can be updated programmatically at any time by calling the respective setter methods on the active keyboard view.

Summary

  • Flick sensitivity controls the pixel threshold distinguishing taps from flicks, defaulting to 100 pixels and configurable via setFlickSensitivityValue().
  • Angle ranges define the directional segments for circular-flick keyboards using a Map<FlickDirection, Pair<Float, Float>> of start angles and sweeps.
  • Key files include FlickKeyboardView.kt for implementation, IMEService.kt for preference application, and CircularFlickSettingsFragment.kt for UI-based customization.
  • Both mechanisms can be adjusted programmatically or through the Settings UI, allowing real-time adaptation to user preferences and device characteristics.

Frequently Asked Questions

How do I make the keyboard more sensitive to short flick gestures?

Decrease the flick sensitivity value below the default of 100 pixels. Call setFlickSensitivityValue(60) on your keyboard view instance, or adjust the preference in pref_custom.xml to a lower value. Smaller numbers require less finger travel to trigger a flick action.

Can I change the angle ranges for the circular flick without modifying source code?

Yes. The CircularFlickSettingsFragment provides a visual interface for adjusting start angles and sweep sizes for each directional segment. Changes are persisted and applied automatically to the active keyboard view via setAngleAndRange(). You only need to modify source code if you want to change the default hard-coded values in FlickKeyboardView.kt.

What happens if I provide an incomplete angle range map?

The keyboard view checks if customAngleAndRange is empty before creating the controller. If your map is missing entries or is empty, the system falls back to the default angle map defined in the attachKeyBehavior block. Always ensure your map contains all four FlickDirection entries (UP, DOWN, UP_RIGHT_FAR, UP_LEFT_FAR) for predictable behavior.

Where is the flick sensitivity threshold actually enforced?

The threshold is enforced in the motion event handling logic of each keyboard view. In FlickKeyboardView.kt (around line 1840), the code compares the absolute distance of touch movement against flickSensitivity. If both X and Y distances are below the threshold, the gesture is classified as a GestureType.Tap; otherwise, it proceeds to flick detection and angle calculation.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →