diff --git a/android/src/main/java/com/capacitorjs/plugins/keyboard/Keyboard.java b/android/src/main/java/com/capacitorjs/plugins/keyboard/Keyboard.java index a31085c..1e4277e 100644 --- a/android/src/main/java/com/capacitorjs/plugins/keyboard/Keyboard.java +++ b/android/src/main/java/com/capacitorjs/plugins/keyboard/Keyboard.java @@ -58,21 +58,6 @@ public Keyboard(AppCompatActivity activity, boolean resizeOnFullScreen) { FrameLayout content = activity.getWindow().getDecorView().findViewById(android.R.id.content); rootView = content.getRootView(); - ViewCompat.setOnApplyWindowInsetsListener(content, (v, insets) -> { - WindowInsetsCompat rootInsets = ViewCompat.getRootWindowInsets(rootView); - if (rootInsets == null) return insets; - - boolean showingKeyboard = rootInsets.isVisible(WindowInsetsCompat.Type.ime()); - - if (resizeOnFullScreen) { - possiblyResizeChildOfContent(showingKeyboard); - } - - v.onApplyWindowInsets(insets.toWindowInsets()); - - return insets; - }); - ViewCompat.setWindowInsetsAnimationCallback( rootView, new WindowInsetsAnimationCompat.Callback(WindowInsetsAnimationCompat.Callback.DISPATCH_MODE_STOP) { @@ -98,10 +83,6 @@ public WindowInsetsAnimationCompat.BoundsCompat onStart( DisplayMetrics dm = activity.getResources().getDisplayMetrics(); final float density = dm.density; - if (resizeOnFullScreen) { - possiblyResizeChildOfContent(showingKeyboard); - } - if (showingKeyboard) { keyboardEventListener.onKeyboardEvent(EVENT_KB_WILL_SHOW, Math.round(imeHeight / density)); } else { @@ -131,6 +112,13 @@ public void onEnd(@NonNull WindowInsetsAnimationCompat animation) { mChildOfContent = content.getChildAt(0); frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams(); + + if (resizeOnFullScreen) { + ViewCompat.setOnApplyWindowInsetsListener(content, (view, windowInsets) -> { + possiblyResizeChildOfContent(windowInsets.isVisible(WindowInsetsCompat.Type.ime())); + return ViewCompat.onApplyWindowInsets(view, windowInsets); + }); + } } public void show() { @@ -154,8 +142,17 @@ private void possiblyResizeChildOfContent(boolean keyboardShown) { return; } - int usableHeightNow = keyboardShown ? computeUsableHeight() : -1; - if (usableHeightPrevious != usableHeightNow) { + if (!keyboardShown) { + if (frameLayoutParams.height != FrameLayout.LayoutParams.MATCH_PARENT) { + frameLayoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + mChildOfContent.requestLayout(); + } + usableHeightPrevious = FrameLayout.LayoutParams.MATCH_PARENT; + return; + } + + int usableHeightNow = computeUsableHeight(); + if (usableHeightPrevious != usableHeightNow || frameLayoutParams.height != usableHeightNow) { frameLayoutParams.height = usableHeightNow; mChildOfContent.requestLayout(); usableHeightPrevious = usableHeightNow; @@ -165,6 +162,16 @@ private void possiblyResizeChildOfContent(boolean keyboardShown) { private int computeUsableHeight() { Rect r = new Rect(); mChildOfContent.getWindowVisibleDisplayFrame(r); + if (shouldApplyEdgeToEdgeAdjustments()) { + WindowInsetsCompat insets = ViewCompat.getRootWindowInsets(rootView); + if (insets != null) { + int systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom; + if (systemBars > 0) { + return r.bottom + systemBars; + } + } + } + return isOverlays() ? r.bottom : r.height(); } @@ -177,6 +184,25 @@ private static boolean isSystemBarsPluginPresent() { } } + private boolean shouldApplyEdgeToEdgeAdjustments() { + var adjustMarginsForEdgeToEdge = this.bridge == null ? "auto" : this.bridge.getConfig().adjustMarginsForEdgeToEdge(); + if (adjustMarginsForEdgeToEdge.equals("force")) { // Force edge-to-edge adjustments regardless of app settings + return true; + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM && adjustMarginsForEdgeToEdge.equals("auto")) { // Auto means that we need to check the app's edge-to-edge preference + TypedValue value = new TypedValue(); + boolean optOutAttributeExists = activity + .getTheme() + .resolveAttribute(android.R.attr.windowOptOutEdgeToEdgeEnforcement, value, true); + + if (!optOutAttributeExists) { // Default is to apply edge to edge + return true; + } else { + return value.data == 0; + } + } + return false; + } + @SuppressWarnings("deprecation") private boolean isOverlays() { final Window window = activity.getWindow();