# Liquid Glass Effect Implementation in Japanese Keyboard: How to Enable and Customize Frosted Glass Themes

> Discover the liquid glass effect implementation in kazumaproject/japanesekeyboard. Learn how to enable and customize frosted glass themes by adjusting SharedPreferences for a stunning visual upgrade.

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

---

**The liquid glass effect in kazumaproject/japanesekeyboard creates a frosted glass appearance by applying variable alpha transparency to key backgrounds and the keyboard root view, controlled through three SharedPreferences values consumed at runtime by `IMEService` and propagated to all keyboard view classes.**

The kazumaproject/japanesekeyboard Android IME implements a sophisticated visual customization system that transforms the keyboard's appearance using runtime drawable manipulation. This **liquid glass effect** (labeled as "Glass Effect" in the user interface) allows users to adjust key transparency and background blur intensity independently, creating a modern aesthetic that blends with underlying application content. Understanding the implementation requires examining the interplay between preference persistence in [`AppPreference.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/AppPreference.kt), the settings UI hosted in [`KeyboardThemeFragment.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/KeyboardThemeFragment.kt), and the rendering pipeline orchestrated by [`IMEService.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/IMEService.kt).

## Architecture of the Liquid Glass Effect Implementation

The implementation spans three architectural layers: preference storage, settings presentation, and runtime rendering across multiple keyboard view classes.

### Preference Storage and Defaults (AppPreference.kt)

In [`AppPreference.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/AppPreference.kt) (lines 248–250 and 1192–1228), the system defines three preference keys with default values that control the effect:

```kotlin
private val LIQUID_GLASS_ENABLE = Pair("liquid_glass_preference", false)
private val LIQUID_GLASS_BLUR_RADIUS = Pair("liquid_glass_blur_preference", 220)
private val LIQUID_GLASS_KEY_ALPHA = Pair("liquid_glass_key_alpha_preference", 255)

var liquid_glass_preference: Boolean   // Controls enable/disable state
var liquid_glass_blur_radius: Int      // Background blur intensity (default: 220)
var liquid_glass_key_alpha: Int        // Key transparency level (default: 255/opaque)

```

These values persist via Android `SharedPreferences`. When the keyboard service initializes, [`IMEService.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/IMEService.kt) reads these stored values to configure the visual appearance dynamically.

### Settings User Interface (KeyboardThemeFragment.kt)

The user-facing controls reside in [`KeyboardThemeFragment.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/KeyboardThemeFragment.kt) (lines 34–119), which exposes three interactive elements:

- **SwitchPreferenceCompat**: Toggles the `liquid_glass_preference` boolean (displayed as "Glass Effect")
- **SeekBarPreference**: Adjusts `liquid_glass_blur_preference` (blur radius, default 220)
- **SeekBarPreference**: Adjusts `liquid_glass_key_alpha_preference` (key transparency, range 0–255)

When the switch changes state, the code enables or disables the blur and alpha sliders accordingly:

```kotlin
liquidGlassBlurPref.isEnabled = isEnabled

```

### Runtime Rendering Pipeline (IMEService.kt)

[`IMEService.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/IMEService.kt) serves as the central coordinator, reading preferences during keyboard initialization (lines 1018–1020) and passing them to view constructors (lines 1223–1226):

```kotlin
// Inside initKeyboard()
liquidGlassThemePreference = liquid_glass_preference
liquidGlassBlurRadiousPreference = liquid_glass_blur_radius
liquidGlassKeyBlurRadiousPreference = liquid_glass_key_alpha

// Passed to keyboard views
liquidGlassEnable = liquidGlassThemePreference ?: false,
liquidGlassKeyAlphaEnable = liquidGlassKeyBlurRadiousPreference ?: 255,

```

For background blur, `IMEService` applies alpha to the root view when the effect is active (lines 1392–1395):

```kotlin
if (liquidGlassThemePreference == true) {
    mainView.root.setDrawableAlpha(liquidGlassBlurRadiousPreference ?: 220)
}

```

## How to Enable the Liquid Glass Effect in Themes

You can activate the frosted glass appearance through the settings UI or programmatically via `SharedPreferences`.

### Enabling Through the Keyboard Theme Settings

1. Open the application and navigate to **Settings** → **Keyboard Theme**
2. Toggle the **"Glass Effect"** switch (internally `liquid_glass_preference`)
3. Adjust the **Blur** slider to control background frosted glass intensity (higher values increase blur)
4. Adjust the **Key Alpha** slider to set key transparency (255 = fully opaque, lower values = more transparent)

Changes save immediately to `SharedPreferences`. The keyboard applies these settings automatically the next time the input view is created or rebuilt.

### Programmatic Configuration via SharedPreferences

To enable the liquid glass effect programmatically from an Activity or Service:

```kotlin
// Obtain the SharedPreferences instance
val prefs = context.getSharedPreferences("app_preferences", Context.MODE_PRIVATE)

// Configure the effect parameters
prefs.edit()
    .putBoolean("liquid_glass_preference", true)       // Enable glass effect
    .putInt("liquid_glass_blur_preference", 250)       // Set blur radius
    .putInt("liquid_glass_key_alpha_preference", 180)  // Set semi-transparent keys
    .apply()

// Force keyboard reload to apply changes immediately
// (Implementation depends on your IME service architecture)

```

## Technical Deep Dive: Rendering Implementation

The visual effect relies on a utility extension and consistent application across all keyboard layout implementations.

### The Drawable Alpha Extension (Drawable.kt)

Located in the core module at [`Drawable.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/Drawable.kt) (line 177), the `setDrawableAlpha` extension function modifies view transparency:

```kotlin
fun View.setDrawableAlpha(alpha: Int) {
    background?.alpha = alpha
    // Handles compound drawables if present
}

```

This utility applies alpha values directly to the view's background drawable, enabling the semi-transparent appearance without complex shader operations.

### Per-View Application Across Keyboard Layouts

Every keyboard view class implements identical logic to check the `liquidGlassEnable` flag and apply transparency. In [`QWERTYKeyboardView.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/QWERTYKeyboardView.kt) (around line 345) and corresponding locations in [`TabletKeyboardView.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/TabletKeyboardView.kt), [`TenKey.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/TenKey.kt), [`CustomSymbolKeyboardView.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/CustomSymbolKeyboardView.kt), and [`FlickKeyboardView.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/FlickKeyboardView.kt), the code follows this pattern:

```kotlin
if (liquidGlassEnable) {
    btn.setDrawableAlpha(liquidGlassKeyAlphaEnable)
}

```

This ensures consistent appearance across **QWERTY**, **Tablet**, **Ten-Key (numeric)**, **Custom Symbol**, and **Flick** keyboard layouts.

### Background Blur Application

While individual keys use the alpha extension for transparency, the background blur effect applies separately to the keyboard's root container. `IMEService` handles this during view inflation, creating the layered frosted glass aesthetic where background content appears blurred while keys maintain their configured opacity level.

## Summary

- **Three preference values** control the liquid glass effect: `liquid_glass_preference` (boolean toggle), `liquid_glass_blur_preference` (integer radius), and `liquid_glass_key_alpha_preference` (integer alpha 0–255).
- **[`AppPreference.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/AppPreference.kt)** manages persistence while **[`KeyboardThemeFragment.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/KeyboardThemeFragment.kt)** provides the user interface for adjusting these values.
- **[`IMEService.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/IMEService.kt)** reads preferences during keyboard initialization and propagates them to specialized view classes including [`QWERTYKeyboardView.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/QWERTYKeyboardView.kt), [`TabletKeyboardView.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/TabletKeyboardView.kt), and [`TenKey.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/TenKey.kt).
- **[`Drawable.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/Drawable.kt)** provides the `setDrawableAlpha` extension function that applies transparency to key backgrounds by modifying drawable alpha properties.
- Changes take effect immediately upon keyboard view recreation, either through the settings toggle or programmatic `SharedPreferences` updates.

## Frequently Asked Questions

### What files control the liquid glass effect rendering?

The implementation spans eight primary files: [`AppPreference.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/AppPreference.kt) (lines 248–250, 1192–1228) handles storage; [`KeyboardThemeFragment.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/KeyboardThemeFragment.kt) (lines 34–119) manages the UI; [`IMEService.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/IMEService.kt) (lines 1018–1020, 1223–1226, 1392–1395) coordinates runtime application; and the view classes [`QWERTYKeyboardView.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/QWERTYKeyboardView.kt), [`TabletKeyboardView.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/TabletKeyboardView.kt), [`TenKey.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/TenKey.kt), [`FlickKeyboardView.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/FlickKeyboardView.kt), and [`CustomSymbolKeyboardView.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/CustomSymbolKeyboardView.kt) apply the effect to individual keys. The core utility resides in [`Drawable.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/Drawable.kt) (line 177).

### How do I programmatically enable the glass effect without using the settings UI?

Access the `SharedPreferences` instance named "app_preferences" and set the three required values: `liquid_glass_preference` to `true`, `liquid_glass_blur_preference` to your desired radius (default 220), and `liquid_glass_key_alpha_preference` to your preferred transparency level (0–255). The keyboard service reads these values during the next view creation cycle.

### Can I adjust the transparency of individual keys separately from the background blur?

Yes. The architecture separates these concerns through two distinct preference keys. `liquid_glass_key_alpha_preference` controls individual key button transparency applied via `setDrawableAlpha()` in keyboard view classes, while `liquid_glass_blur_preference` controls the root view background blur applied in [`IMEService.kt`](https://github.com/kazumaproject/japanesekeyboard/blob/main/IMEService.kt). You can configure opaque keys with blurred backgrounds, or vice versa, by adjusting these values independently.

### Why isn't the liquid glass effect appearing after I enable it in preferences?

The effect requires a keyboard view recreation to take effect, as `IMEService` reads preferences during `initKeyboard()` and passes them to view constructors. If the keyboard remains visible, the changes apply the next time the input method is shown or when the user switches keyboard layouts. For immediate application, the IME must trigger a view rebuild or the user must hide and reopen the keyboard.