react-native-screens icon indicating copy to clipboard operation
react-native-screens copied to clipboard

fix(Android): handle keyboard and formsheet together

Open maciekstosio opened this issue 8 months ago • 3 comments

Description

Fixes https://github.com/software-mansion/react-native-screens/issues/2774, #2664

This issue aims to improve keyboard handling when using formsheet. Currently, we cover the formsheet and move to highest intent (when there are multiple) + force keyboard hide while swiping down. This sometimes look glitchy and causes formsheet to be covered in some scenarios.

Changes

I tested the Jetpack Compose version of form sheet and it didn't really seem to provide consistent experience as it is on iOS, so we modeled the solution to resemble iOS.

Before keyboard and formsheet were independent - one didn't animated with the other. For cases other than fitToContents when keyboard was opened the intent was bumped. When changing intent by swipe gesture, keyboard was dismissed.

New solution consist of three parts:

  • Changing intent - this part works as before
  • Animation - formsheet is translated based on ime animation progress by WindowInsetsAnimationCompat.Callback
  • Close gesture - when keyboard is opened BottomSheetBehavior onTouchEvent is overridden and is used to swipe down the keyboard, SimpleImeAnimationController is used to control keyboard based on https://youtu.be/acC7SR1EXsI?feature=shared&t=718

When keyboard is open on the previous screen, we force trigger onApplyWindowInsets to update screen transitionX based on the keyboard height.

Animating keyboard and controlling it is available from Android API 30, so for backward compatibility we set translateX in onApplyWindowInsets.

Screenshots / GIFs

One intent

iOS Android Before Android After

Two intents

iOS Android Before Android After

Three intents

iOS Android Before Android After

Test code and steps to reproduce

See Test2774.tsx

How this has been tested

  • Open formsheet, and check all intents (if available)
  • Open form sheet and focus text input - formsheet should be animated with the keyboard by keyboard height or max available space
  • Check if keyboard can be closed by gesture
  • Check if keyboard can be closed by close button
  • Check Android prior API 30
  • Check if the formsheet isn't translated outside of the window
  • Check if formsheet isn't covered when there is keyboard already opened on the previous screen

Checklist

  • [ ] Included code example that can be used to test this change
  • [ ] Ensured that CI passes

maciekstosio avatar May 15 '25 09:05 maciekstosio

Hey @maciekstosio

I noticed this work and thought it would be reasonable to create a discussion here. Do you think this functionality can be achieved using KeyboardGestureArea from react-native-keyboard-controller?

I understand the idea behind "a single package can handle navigation/keyboard management", but I also would love to see less DRY in the react-native ecosystem and more composability?..

Would love to know if the result that you are trying to achieve is not possible to achieve with KeyboardGestureArea and if not then maybe I can help to implement it in react-native-keyboard-controller? 👀

kirillzyusko avatar May 19 '25 18:05 kirillzyusko

This looks amazing!

Keyboard handling is the last issues that I have on new arch to make it work flawlessly. 🤞

RohovDmytro avatar Jun 04 '25 01:06 RohovDmytro

Hey guys, is there any plans to merge it soon?

athusrv avatar Jun 18 '25 00:06 athusrv

Hi, when are you planning to merge? This is a merge that many people are really waiting for.

fukuli053 avatar Aug 13 '25 08:08 fukuli053

Up! up!

ArviinM avatar Aug 31 '25 15:08 ArviinM

Ping @kkafar

ajanuar avatar Nov 03 '25 12:11 ajanuar

The work progresses here: https://github.com/software-mansion/react-native-screens/pull/3248

kkafar avatar Nov 07 '25 16:11 kkafar