fix(Android, FormSheet v4): refine keyboard avoidance to prevent layout reflows with SafeAreaView#4244
Open
t0maboro wants to merge 4 commits into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Refines Android FormSheet (stack v4) keyboard avoidance to prevent global layout reflows by keeping window insets unchanged and instead adjusting the sheet position via translationY in SheetAnimationCoordinator. This fits into the library’s native bottom sheet implementation used for the formSheet presentation mode.
Changes:
- Stop consuming/modifying decor-view window insets in
SheetDelegate(return insets unmodified). - Rework keyboard avoidance to compute a keyboard-driven
translationYshift that accounts for nested container bottom offsets and navigation bar overlap. - Add a new issue test (Test4244) covering the scenario.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| apps/src/tests/issue-tests/Test4244.tsx | Adds a repro/test screen for FormSheet + SafeAreaView keyboard avoidance behavior. |
| apps/src/tests/issue-tests/index.ts | Exports the new Test4244 entry. |
| android/src/main/java/com/swmansion/rnscreens/bottomsheet/SheetDelegate.kt | Stops modifying returned insets at the decor-view level to avoid global layout jumps. |
| android/src/main/java/com/swmansion/rnscreens/bottomsheet/SheetAnimationCoordinator.kt | Implements translation-based keyboard avoidance with nav-bar overlap compensation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
4 tasks
t0maboro
added a commit
that referenced
this pull request
Jul 1, 2026
…board appear in nested containers (#4240) ## Description When a `FormSheet` is presented from a container that does not reach the absolute bottom of the screen (e.g., a stack nested inside bottom tabs), opening the keyboard causes the sheet to translate too far up. This happens because `SheetAnimationCoordinator` previously assumed the sheet's container always starts at the absolute bottom of the window. It applied the full, raw IME inset height to `translationY`. As a result, a visible gap appeared between the keyboard and the bottom of the sheet. Instead of applying the raw keyboard height, we now calculate the `effectiveKeyboardHeight` by subtracting the space below the sheet's container from the raw IME inset. ## Changes - use getGlobalVisibleRect to find the absolute position of the container's bottom and subtract it from the root view's height. - calculate and cache the offset only when necessary: inside `onAnimationStart` and `notifyKeyboardAnimationStart`. --- > [!WARNING] > While debugging, I noticed another related issue in `SheetDelegate`. When the IME becomes visible, the delegate intercepts the insets (currently from DecorView) and explicitly zeroes out the bottom system bar (navigation bar) inset for the entire hierarchy https://github.com/software-mansion/react-native-screens/blob/4.25.2/android/src/main/java/com/swmansion/rnscreens/bottomsheet/SheetDelegate.kt#L376-L389 > As a result, the moment the keyboard starts sliding up, every screen receives a 0 navigation bar inset. This causes the screen's layout height to instantly increase, leading to a noticeable visual jump in its content. We should address this in a follow-up, as it seems like the FormSheet delegate shouldn't inappropriately modify or consume the navigation bar insets for the rest of the view tree. > > Fixed in a followup PR: #4244 ## Before & after - visual documentation | Before | After | | --- | --- | | <video src="https://github.com/user-attachments/assets/734c5d82-c385-4ca3-aa4d-b07edafbed63" /> | <video src="https://github.com/user-attachments/assets/55dbba7e-562f-4573-984e-02918d520e6f" /> | ## Test plan Adding dedicated issue test in this PR ## Checklist - [ ] Included code example that can be used to test this change. - [ ] For visual changes, included screenshots / GIFs / recordings documenting the change. - [ ] For API changes, updated relevant public types. - [ ] Ensured that CI passes
Base automatically changed from
@t0maboro/adjust-formsheet-keyboard-offset-in-nested-container
to
main
July 1, 2026 13:27
f6c2292 to
bf748bb
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Previously, handling keyboard appearance involved modifying window insets on the DecorView level, what caused issues with layout jumping in the whole native hierarchy. We have reworked this model to keep the sheet size stable, relying entirely on
translationYadjustments driven by SheetAnimationCoordinator. The logic dynamically calculateskeyboardHeightInContainerBoundsandnavigationBarHeightWithinContainer. This ensures the translation works when the sheet is placed inside a nested container with its own bottom offset.Changes
calculateKeyboardShiftHidingBottomInset()to compute the exacttranslationYcorrection to properly avoid the keyboard. Instead of lifting the entire sheet, which would push the content too high and leave a content gap caused by the navigation bar, the new logic subtracts the navigation bar overlap from the maximum possible/required keyboard lift.Before & after - visual documentation
Test4240
test4240.mov
Test4240.mov
Test4244
test4244.mov
Test4244.mov
Test plan
Added Test4244.
Checklist