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:
8
android/src/main/jni/CMakeLists.txt
Normal file
8
android/src/main/jni/CMakeLists.txt
Normal 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")
|
||||
53
android/src/main/jni/keyboard_bridge.c
Normal file
53
android/src/main/jni/keyboard_bridge.c
Normal 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++;
|
||||
}
|
||||
Reference in New Issue
Block a user