test(android): Adjust system keyboard insets

This commit is contained in:
Darcy Wong 2025-10-07 08:36:20 +07:00
parent 6205190597
commit 295dfd9e92
3 changed files with 58 additions and 49 deletions

View file

@ -246,21 +246,17 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven
inputViewHeight = inputView.getHeight();
}
int navigationHeight = KMManager.getNavigationBarHeight(this);
int bannerHeight = KMManager.getBannerHeight(this);
int kbHeight = KMManager.getKeyboardHeight(this);
outInsets.contentTopInsets = inputViewHeight - bannerHeight - kbHeight;
// TODO - design better way to toggle this adjustment
SharedPreferences prefs = this.getSharedPreferences(PreferencesManager.kma_prefs_name, Context.MODE_PRIVATE);
boolean showOSK = prefs.getBoolean(KeymanSettingsActivity.oskWithPhysicalKeyboardKey, false);
if (showOSK) {
outInsets.contentTopInsets -= navigationHeight;
}
int bottomInset = KMManager.getBottomInset();
outInsets.contentTopInsets = inputViewHeight - bannerHeight - kbHeight - bottomInset;
outInsets.visibleTopInsets = outInsets.contentTopInsets;
outInsets.touchableInsets = InputMethodService.Insets.TOUCHABLE_INSETS_REGION;
outInsets.touchableRegion.set(0, outInsets.contentTopInsets, size.x, size.y);
//Log.d(TAG, String.format("inputView: %d, , bannerHeight: %d, kbHeight: %d, navigationHeight: %d",
// inputViewHeight, bannerHeight, kbHeight, navigationHeight));
}
@Override

View file

@ -101,7 +101,7 @@ public class BaseActivity extends AppCompatActivity {
insets.bottom);
KMManager.applyInsetsToKeyboard(
KMManager.KeyboardType.KEYBOARD_TYPE_INAPP, insets.left, insets.right, insets.bottom);
insets.left, insets.right, insets.bottom);
return windowInsets;
});
}

View file

@ -54,6 +54,7 @@ import android.widget.RelativeLayout;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.DisplayCutoutCompat;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
@ -90,6 +91,7 @@ public final class KMManager {
private static final String TAG = "KMManager";
private static ResourcesUpdateTool updateTool;
private static int bottomInset;
// Keyboard types
public enum KeyboardType {
@ -705,10 +707,6 @@ public final class KMManager {
public static RelativeLayout.LayoutParams getKeyboardLayoutParams() {
int bannerHeight = getBannerHeight(appContext);
int kbHeight = getKeyboardHeight(appContext);
int navigationHeight = getNavigationBarHeight(appContext);
int orientation = getOrientation(appContext);
FormFactor formFactor = getFormFactor();
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, bannerHeight + kbHeight);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
@ -717,25 +715,25 @@ public final class KMManager {
/**
* Applies padding to the keyboard so it's not covered by system insets
* @param {KeyboardType} keyboard
* @param left int padding to account for notch/navigation bar on left side of screen
* @param right int padding to account for notch/navigation bar on right side of screen
* @param bottom int padding to account for navigation bar on bottom of screen
*/
public static void applyInsetsToKeyboard(KeyboardType keyboardType, int left, int right, int bottom) {
if (keyboardType == KeyboardType.KEYBOARD_TYPE_INAPP && InAppKeyboard != null) {
public static void applyInsetsToKeyboard(int left, int right, int bottom) {
if (InAppKeyboard != null) {
applyInsetsPaddingToKeyboardView(InAppKeyboard, left, right, bottom);
}
if (keyboardType == KeyboardType.KEYBOARD_TYPE_SYSTEM && SystemKeyboard != null) {
if (SystemKeyboard != null) {
applyInsetsPaddingToKeyboardView(SystemKeyboard, left, right, bottom);
}
}
private static void applyInsetsPaddingToKeyboardView(KMKeyboard keyboard, int left, int right, int bottom) {
View parent = (View) keyboard.getParent();
bottomInset = bottom;
if (keyboard.keyboardType == KeyboardType.KEYBOARD_TYPE_INAPP && parent != null) {
if (parent != null) {
// Keep existing top padding, add bottom padding for the inset
parent.setPadding(
left,
@ -757,6 +755,10 @@ public final class KMManager {
}
}
public static int getBottomInset() {
return bottomInset;
}
private static void initKeyboard(Context appContext, KeyboardType keyboardType) {
KMKeyboard keyboard = null;
KMKeyboardWebViewClient webViewClient = null;
@ -891,40 +893,49 @@ public final class KMManager {
mainLayout.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
if (SystemKeyboard == null) {
installSystemKeyboardInsetsListener(mainLayout);
return mainLayout;
}
if (mainLayout != null) {
// Update insets
ViewCompat.setOnApplyWindowInsetsListener(mainLayout,
(view, windowInsets) -> {
// Allocate insets for system bars and display cutout (notch)
Insets insets = windowInsets.getInsets(
WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout());
view.setPadding(
insets.left,
insets.top,
insets.right,
insets.bottom);
applyInsetsToKeyboard(KeyboardType.KEYBOARD_TYPE_SYSTEM, insets.left, insets.right, insets.bottom);
return windowInsets;
});
}
RelativeLayout keyboardLayout = new RelativeLayout(appContext);
keyboardLayout.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
ViewGroup parent = (ViewGroup) SystemKeyboard.getParent();
if (parent != null)
if (parent != null) {
parent.removeView(SystemKeyboard);
}
keyboardLayout.addView(SystemKeyboard);
mainLayout.addView(keyboardLayout);
//mainLayout.addView(overlayLayout);
installSystemKeyboardInsetsListener(mainLayout);
return mainLayout;
}
private static void installSystemKeyboardInsetsListener(View anchor) {
ViewCompat.setOnApplyWindowInsetsListener(anchor, (v, insets) -> {
// System bars (status bar and navigation bar)
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
// Cutout (camera notch) safe insets
DisplayCutoutCompat cutout = insets.getDisplayCutout();
int safeLeft = (cutout != null) ? cutout.getSafeInsetLeft() : 0;
int safeRight = (cutout != null) ? cutout.getSafeInsetRight() : 0;
int leftInset = Math.max(systemBars.left, safeLeft);
int rightInset = Math.max(systemBars.right, safeRight);
boolean imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime());
int bottomInset = systemBars.bottom;
applyInsetsToKeyboard(leftInset, rightInset, bottomInset);
return insets;
});
// Trigger an initial pass
ViewCompat.requestApplyInsets(anchor);
}
public static void onStartInput(EditorInfo attribute, boolean restarting) {
if (!restarting && SystemKeyboard != null) {
String packageName = attribute.packageName;
@ -2493,6 +2504,15 @@ public final class KMManager {
KeyboardHeight_Context_Landscape_Default = (int) newResources.getDimension(R.dimen.keyboard_height);
}
public static int getStatusBarHeight(Context context) {
int statusBarHeight = 0;
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
statusBarHeight = context.getResources().getDimensionPixelSize(resourceId);
}
return statusBarHeight;
}
/**
* Get the navigation bar height (if visible) in pixels
* @param context - the context
@ -2506,12 +2526,8 @@ public final class KMManager {
if (windowManager != null) {
WindowInsets insets = windowManager.getCurrentWindowMetrics().getWindowInsets();
android.graphics.Insets systemBarInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars());
android.graphics.Insets gestureInsets = insets.getInsets(WindowInsetsCompat.Type.systemGestures());
boolean gestureInsetsVisible = insets.isVisible(WindowInsetsCompat.Type.systemGestures());
android.graphics.Insets navigationInsets = insets.getInsets(WindowInsetsCompat.Type.navigationBars());
boolean navigationInsetsVisible = insets.isVisible(WindowInsetsCompat.Type.navigationBars());
if (gestureInsets.bottom != navigationInsets.bottom) {
navigationBarHeight = gestureInsets.bottom;
@ -2519,11 +2535,8 @@ public final class KMManager {
navigationBarHeight = systemBarInsets.bottom;
}
Log.d(TAG, String.format("gesture.visible %s, bottom: %d; navigation.visible %s, bottom: %d; systemBar.bottom %d; px density: %f",
gestureInsetsVisible, gestureInsets.bottom,
navigationInsetsVisible, navigationInsets.bottom,
systemBarInsets.bottom,
getWindowDensity(context)));
Log.d(TAG, String.format("gesture.bottom: %d; navigation.bottom: %d; systemBar.bottom %d",
gestureInsets.bottom, navigationInsets.bottom, systemBarInsets.bottom));
}
} else {
// Determine if navigation bar is visible
@ -2540,7 +2553,7 @@ public final class KMManager {
context.getResources().getDimensionPixelSize(resourceId) : 0;
}
return (int)(navigationBarHeight);
return navigationBarHeight;
}
/**