Skip to content

Android: keyboard open/close doesn't move input area correctly #89

@begna112

Description

@begna112

Description

On Android, the text input area (composer, buttons, send button) does not properly follow the keyboard when it opens or closes:

  • Keyboard close: The input area stays floating in the middle of the screen and may eventually drop to the bottom, but often gets stuck there.
  • Keyboard open: The input area is delayed and ends up partially behind the keyboard, with the settings row and send button obscured.

Root Cause

The app has two platform-specific implementations of AgentContentView:

  • AgentContentView.ios.tsx — Uses useReanimatedKeyboardAnimation() and useKeyboardHandler() worklets to animate the input area in sync with the keyboard, frame-by-frame. Works correctly.

  • AgentContentView.tsx (default, used on Android) — Uses only useKeyboardState(), which provides a binary isVisible boolean and a static height. It applies a static paddingBottom to the outer container rather than animated transforms:

    // Line 19 - the entire keyboard handling on Android
    paddingBottom: state.isVisible ? state.height - safeArea.bottom : 0

This is fundamentally broken because react-native-keyboard-controller's KeyboardProvider puts Android into edge-to-edge mode and effectively disables the system's built-in adjustResize behavior. The library expects the app to manually handle keyboard positioning using its animated values — which the iOS version does, but the Android version does not.

The result is the worst of both worlds: no system-level keyboard avoidance AND no app-level animated avoidance. The static paddingBottom approach can't track the keyboard's animation, leading to the input being stuck in the middle (on close) or behind the keyboard (on open).

Affected Files

  • apps/ui/sources/components/sessions/transcript/AgentContentView.tsx (Android — broken)
  • apps/ui/sources/components/sessions/transcript/AgentContentView.ios.tsx (iOS — working reference)

Suggested Fix

The Android implementation should use the same animated approach as iOS:

  1. Use useReanimatedKeyboardAnimation() instead of useKeyboardState() — this provides frame-synced animated height/progress values that work on Android
  2. Use useKeyboardHandler() worklets for animation lifecycle
  3. Apply translateY transforms via Animated.View on both the content and input areas, matching the iOS implementation
  4. The existing iOS file can serve as a direct reference — react-native-keyboard-controller supports all of these APIs on Android

Notably, the dev tools screen (apps/ui/sources/app/(app)/dev/inverted-list.tsx) already uses useReanimatedKeyboardAnimation() on all platforms, confirming this approach works on Android.

Environment

  • Android APK (preview build from GitHub releases)
  • react-native-keyboard-controller v1.18.5

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions