Skip to content

fix: double keyboard height#1131

Merged
kirillzyusko merged 3 commits intomainfrom
fix/double-keyboard-height
Sep 25, 2025
Merged

fix: double keyboard height#1131
kirillzyusko merged 3 commits intomainfrom
fix/double-keyboard-height

Conversation

@kirillzyusko
Copy link
Copy Markdown
Owner

@kirillzyusko kirillzyusko commented Sep 24, 2025

📜 Description

Fix the issue with double height when react-native-keyboard-controller and react-native-unistyles used together.

💡 Motivation and Context

It turns out that replaceSystemWindowInsets method is deprecated on Android. In fact it also overwrite Android behavior. Starting from API 30+ all insets are divided into categories: nav bar insets, status bar insets, keyboard insets etc. When we call replaceSystemWindowInsets we may mess up systemBar insets. How? As per Android specification:

The status bar, caption bar, and navigation bar are called the system bars.

However when we call replaceSystemWindowInsets and keyboard is currently visible (and keyboard is treated as system window inset) then we force-include keyboard insets in systemBar. When react-native-unistyles read system insets they get keyboard inset instead of bottom-safe-area. I tried to change a code, but if you even explicitly query Type().navigationBars() then keyboard height still included 🤯

Important

The code with replaceSystemWindowInsets was added intentionally. Without this code we have a jump that was described in #1013 (comment)

So to sum up - replaceSystemWindowInsets interfere with systemBar insets (keyboard height becomes included). Initial fix was attempted to make in 5f7d16e (we can not use only navBarInsets.bottom because it will be 48 when edge-to-edge mode gets disabled, so whole screen container gets pushed up and we have empty view in bottom of the screen). In this case we limit system inset to be only bottom tab bar when our view is active and we pass whole system inset when view is disabled (so that Android handles everything correctly/fallbacks to its default behavior).

However then I realized, that e2e tests are failing (basically when keyboard disappear on Android 28 we don't receive onEnd event or receive it with coordinates as keyboard would be open). I thought that it stems from the fact that we are using a deprecated API so I re-worked code in 02f76f3 - it uses modern API, but the fix is very similar to what we had before:

  • first of all we don't overwrite bottom systemBars insets with system values 👍
  • we need to call ViewCompat.onApplyWindowInsets(v, adjustedInsets) (it will prevent fake nav bar apdding from being added)
  • we need to replicate the fix when module is disabled - in this case pass system insets so system will push the content up

However after testing new approach I also realized that e2e tests fails 😡

Turns out the internal implementation of onApplyWindowInsets in compat layer is different, and the easiest fix is to add conditional code, that will run old code for API < 30 and will run new code for APIs > 30. Since the new code was getting bigger and bigger I decided to move it into separate extension where I'm managing all these conditions. That code is complicated, but this is the only one reliable way I found to fix client project + not break example app 😓

📢 Changelog

Android

  • created replaceStatusBarInsets extension;
  • use replaceStatusBarInsets extension in EdgeToEdge view.

🤔 How Has This Been Tested?

Tested in client project on: API 29, API 30, API 31, API 33. Tested example project on API 28 (real device), API 33, API 36 (real device).

📸 Screenshots (if appropriate):

Android 16 (Pixel 7 Pro)

Before After
telegram-cloud-document-2-5379740253873536324.mp4
telegram-cloud-document-2-5379740253873536321.mp4

Android 12 (Pixel 6 Pro, API 31)

Before After
Screen.Recording.2025-09-25.at.13.23.46.mov
Screen.Recording.2025-09-25.at.13.25.40.mov

📝 Checklist

  • CI successfully passed
  • I added new mocks and corresponding unit-tests if library API was changed

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Sep 24, 2025

📊 Package size report

Current size Target Size Difference
223770 bytes 223387 bytes 383 bytes 📈

@kirillzyusko kirillzyusko marked this pull request as ready for review September 25, 2025 11:23
@kirillzyusko kirillzyusko merged commit 0a97fd6 into main Sep 25, 2025
16 checks passed
@kirillzyusko kirillzyusko deleted the fix/double-keyboard-height branch September 25, 2025 11:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🤖 android Android specific 🐛 bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant