android: keyboard height tracking via JNI/FFI bridge

- C bridge (keyboard_bridge.c) stores keyboard state in globals.
  Kotlin writes via JNI, Dart reads via FFI — zero async delay,
  same architecture as iOS.
- WindowInsetsAnimation.Callback tracks open/close per-frame.
- OnGlobalLayoutListener catches silent height changes (emoji
  keyboard resize, floating keyboard toggle).
- Dart animation replay stays iOS-only; Android reads native
  per-frame values directly.
- Cleaned up old Java stub, updated build.gradle for Kotlin + CMake
  with 16KB page alignment (Android 15+).
- Example app rewritten to demonstrate UxKeyboard usage.
This commit is contained in:
agra
2026-04-15 23:49:16 +03:00
parent a1ab667178
commit 0be198e388
13 changed files with 336 additions and 151 deletions

View File

@@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.10)
project(ux_keyboard)
add_library(ux_keyboard SHARED keyboard_bridge.c)
target_link_libraries(ux_keyboard log)
# 16KB page size support (required for Android 15+)
target_link_options(ux_keyboard PRIVATE "-Wl,-z,max-page-size=16384")

View File

@@ -0,0 +1,53 @@
#include <jni.h>
#include <stdint.h>
// Shared state — Kotlin writes, Dart reads via FFI
static double g_keyboard_height = 0;
static double g_system_height = 0;
static int32_t g_is_tracking = 0;
static double g_anim_target = 0;
static double g_anim_duration = 0;
static int32_t g_anim_generation = 0;
// --- Dart FFI reads (same signatures as iOS) ---
double ux_keyboard_height(void) { return g_keyboard_height; }
double ux_system_keyboard_height(void) { return g_system_height; }
int32_t ux_is_tracking(void) { return g_is_tracking; }
double ux_keyboard_anim_target(void) { return g_anim_target; }
double ux_keyboard_anim_duration(void) { return g_anim_duration; }
int32_t ux_keyboard_anim_gen(void) { return g_anim_generation; }
// --- Stubs for Dart FFI parity with iOS ---
void ux_enable_interactive_dismiss(double inset) { (void)inset; }
void ux_disable_interactive_dismiss(void) {}
// --- Kotlin JNI writes ---
JNIEXPORT void JNICALL
Java_io_swipelab_ux_KeyboardBridge_nSetHeight(JNIEnv *env, jclass cls, jdouble h) {
g_keyboard_height = h;
}
JNIEXPORT void JNICALL
Java_io_swipelab_ux_KeyboardBridge_nSetSystemHeight(JNIEnv *env, jclass cls, jdouble h) {
g_system_height = h;
}
JNIEXPORT jdouble JNICALL
Java_io_swipelab_ux_KeyboardBridge_nGetSystemHeight(JNIEnv *env, jclass cls) {
return g_system_height;
}
JNIEXPORT void JNICALL
Java_io_swipelab_ux_KeyboardBridge_nSetTracking(JNIEnv *env, jclass cls, jint v) {
g_is_tracking = v;
}
JNIEXPORT void JNICALL
Java_io_swipelab_ux_KeyboardBridge_nSetAnim(JNIEnv *env, jclass cls, jdouble target, jdouble duration) {
g_anim_target = target;
g_anim_duration = duration;
g_anim_generation++;
}