-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix calculating keyboard height #5851
Fix calculating keyboard height #5851
Conversation
We need this fix 🙏 Temp fix:
|
@kesha-antonov you can also try to use patch from below. Please let me know if that helps with your issue. Patchdiff --git a/node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/keyboard/Keyboard.java b/node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/keyboard/Keyboard.java
index 0f8ae7807..d71bd5f07 100644
--- a/node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/keyboard/Keyboard.java
+++ b/node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/keyboard/Keyboard.java
@@ -1,7 +1,5 @@
package com.swmansion.reanimated.keyboard;
-import android.view.KeyCharacterMap;
-import android.view.KeyEvent;
import androidx.core.view.WindowInsetsCompat;
import com.facebook.react.uimanager.PixelUtil;
@@ -23,9 +21,7 @@ public class Keyboard {
public void updateHeight(WindowInsetsCompat insets) {
int contentBottomInset = insets.getInsets(CONTENT_TYPE_MASK).bottom;
int systemBarBottomInset = insets.getInsets(SYSTEM_BAR_TYPE_MASK).bottom;
- boolean hasNavigationBar = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_HOME);
- int keyboardHeightDip =
- hasNavigationBar ? contentBottomInset - systemBarBottomInset : contentBottomInset;
+ int keyboardHeightDip = contentBottomInset - systemBarBottomInset;
int keyboardHeight = (int) PixelUtil.toDIPFromPixel(Math.max(0, keyboardHeightDip));
if (keyboardHeight == 0 && mState == KeyboardState.OPEN) {
/*
@@ -35,7 +31,7 @@ public class Keyboard {
*/
return;
}
- mHeight = (int) PixelUtil.toDIPFromPixel(keyboardHeightDip);
+ mHeight = keyboardHeight;
}
public void onAnimationStart() {
diff --git a/node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/keyboard/WindowsInsetsManager.java b/node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/keyboard/WindowsInsetsManager.java
index b7ad125e9..353084cf0 100644
--- a/node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/keyboard/WindowsInsetsManager.java
+++ b/node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/keyboard/WindowsInsetsManager.java
@@ -9,7 +9,6 @@ import androidx.core.view.ViewCompat;
import androidx.core.view.WindowCompat;
import androidx.core.view.WindowInsetsCompat;
import com.facebook.react.bridge.ReactApplicationContext;
-import com.swmansion.reanimated.BuildConfig;
import java.lang.ref.WeakReference;
public class WindowsInsetsManager {
@@ -58,24 +57,19 @@ public class WindowsInsetsManager {
}
private WindowInsetsCompat onApplyWindowInsetsListener(View view, WindowInsetsCompat insets) {
+ WindowInsetsCompat defaultInsets = ViewCompat.onApplyWindowInsets(view, insets);
if (mKeyboard.getState() == KeyboardState.OPEN) {
mKeyboard.updateHeight(insets);
mNotifyAboutKeyboardChange.call();
}
- setWindowInsets(insets);
- return insets;
+ setWindowInsets(defaultInsets);
+ return defaultInsets;
}
private void setWindowInsets(WindowInsetsCompat insets) {
- int paddingBottom = 0;
- boolean isOldPaperImplementation =
- !BuildConfig.IS_NEW_ARCHITECTURE_ENABLED && BuildConfig.REACT_NATIVE_MINOR_VERSION < 70;
- if (isOldPaperImplementation) {
- int navigationBarTypeMask = WindowInsetsCompat.Type.navigationBars();
- paddingBottom = insets.getInsets(navigationBarTypeMask).bottom;
- }
int systemBarsTypeMask = WindowInsetsCompat.Type.systemBars();
int paddingTop = insets.getInsets(systemBarsTypeMask).top;
+ int paddingBottom = insets.getInsets(systemBarsTypeMask).bottom;
updateInsets(paddingTop, paddingBottom);
}
@@ -95,7 +89,7 @@ public class WindowsInsetsManager {
FrameLayout.LayoutParams params =
new FrameLayout.LayoutParams(matchParentFlag, matchParentFlag);
if (mIsStatusBarTranslucent) {
- params.setMargins(0, 0, 0, 0);
+ params.setMargins(0, 0, 0, paddingBottom);
} else {
params.setMargins(0, paddingTop, 0, paddingBottom);
} |
Thanks! |
is your keyboard animations on ios looks smooth ? cause on ios they're verry choppy in our app with same code |
It doesn't work on my repro.
|
@TomCorvus Hi, have you tried using |
This option fix the shift. Thanks @maciekstosio |
Hi, I focused on android implementation. It would be great if you could create separate issue if you're having problems on iOS. |
@TomCorvus On Android, to listen to keyboard changes we use immersive mode. It expands root view to full screen and gives away the control over insets management, so we need to apply them ourselves:
|
@TomCorvus I don't think I fully answered your question, it looks that we can do it automatically, you can see it in #5889. |
It was related to bad optimization of chat lib. Made PR there: FaridSafi/react-native-gifted-chat#2493 Sorry for spamming your thread ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👏🎉
<!-- Thanks for submitting a pull request! We appreciate you spending the time to work on these changes. Please follow the template so that the reviewers can easily understand what the code changes affect. --> ## Summary This PR updates the `useAnimatedKeyboard` docs to current doc pattern + add more detailed remarks discovered while doing #5851. It's pointing to #5851 and assumes changes from that PR, so **should be merged after**. ## Test plan ``` cd docs yarn yarn start ``` and go to useAnimatedKeyboard section <!-- Provide a minimal but complete code snippet that can be used to test out this change along with instructions how to run it and a description of the expected behavior. --> --------- Co-authored-by: Tomek Zawadzki <[email protected]> Co-authored-by: Kacper Kapuściak <[email protected]>
Summary
Should fix: #5811
Keyboard height seems to be improperly calculated. Based on my investigation it seems that
WindowInsetsCompat.Type.ime()
includes height of the keyboard + bottom navigation. What Reanimated does currently is checking if navigation bar is visible (KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_HOME);
) and then subtracts the bottom insetint keyboardHeight = DiphasNavigationBar ? contentBottomInset - systemBarBottomInset : contentBottomInset;
. But to my understandinghasNavigationBar
is always true, thus when keyboard is hidden keyboard height becomes-contentBottomInset
. So I changed the navigation height to beMath.max(0, keyboardHeightDip)
Additionally in WindowInsetsManager.java I applied default paddings and added padding bottom which should help correctly position element from the bottom.
Remarks
isStatusBarTranslucentAndroid
doesn't seems to do anything when screen has native header (headerShown: true
)Examples before vs after
Adding useAnimatedKeyboard breaks the layout
adding.useAnimatedKeyboard.Before.mov
adding.useAnimatedKeyboard.After.mov
After closing the keyboard there is unexpected gap (negative height)
topSpace.Before.mov
topSpace.After.mov
When StatusBar is hidden keyboard nor working properly on Android 10 - not fixed but not a regression
statusBar.Before.mov
statusBar.after.mov
Test plan
Example showing the problem