Skip to content
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

Android Keyboard Height - 24px too small (most of the time) #509

Closed
mattlennon3 opened this issue Jul 17, 2024 · 4 comments
Closed

Android Keyboard Height - 24px too small (most of the time) #509

mattlennon3 opened this issue Jul 17, 2024 · 4 comments
Assignees
Labels
🤖 android Android specific question You wanted to clarify something about the usage of the library or have a question about something

Comments

@mattlennon3
Copy link

mattlennon3 commented Jul 17, 2024

Describe the bug
We recently updated to these versions:

react-native-keyboard-controller: 1.9.0 -> 1.12.6

react-native-reanimated: 3.8.1 -> 3.13.0

Since then, we noticed a space appear between the keyboard and our buttons at the bottom of our screens:

Screenshot 2024-07-17 at 16 26 01

I switched between versions and calculated this as exactly 24px difference. I believe it has something do with #468 and the issues it is trying to fix.

Code snippet
I don't have a full repo for you. But I'm happy to share the component we insert at the bottom of any pages which need to avoid the keyboard.

Please ignore the iOS max height code. We also don't pass any extraHeight in for the problem screens. So it is 0.

Otherwise the code is quite close to the example in this repo I believe:

import { useState } from 'react';
import { Platform } from 'react-native';
import { useReanimatedKeyboardAnimation } from 'react-native-keyboard-controller';
import Animated, { runOnJS, useAnimatedStyle, useDerivedValue } from 'react-native-reanimated';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

interface KeyboardBottomPaddingViewProps {
  extraHeight?: number;
}

export const KeyboardBottomPaddingView = ({ extraHeight = 0 }: KeyboardBottomPaddingViewProps) => {
  const { height: kbHeight } = useReanimatedKeyboardAnimation();

  console.log({ kbHeight, statusBarHeight: StatusBar.currentHeight });

  const insets = useSafeAreaInsets();
  const extra = (Platform.OS === 'ios' ? insets.bottom : 0) + extraHeight;

  /** Workaround for an ios keyboard bug, the password prompt jumps on each keydown. So we keep the max height here, unless it goes back to 0. */
  const [maxHeight, setMaxHeight] = useState(kbHeight.value);
  const handleHeightChange = (newHeight: number) => {
    if (newHeight === 0) {
      setMaxHeight(0);
    } else if (newHeight < maxHeight) {
      setMaxHeight(newHeight);
    }
  };
  useDerivedValue(() => {
    runOnJS(handleHeightChange)(kbHeight.value);
  });
  /** End workaround */

  const styles = useAnimatedStyle(() => {
    const height = -maxHeight - extra;
    return {
      height,
    };
  }, [extra, maxHeight]);

  if (!maxHeight) {
    // This will avoid the gap at the bottom when there is no keyboard in the view
    return null;
  }

  return <Animated.View style={styles} />;
};

The logs output from the console here are as follows:

// new version
{"kbHeight": -302.9090881347656, "statusBarHeight": 52.727272033691406}
// old version
{"kbHeight": -278.9090881347656, "statusBarHeight": 52.727272033691406}

It may also be important to note the provider props, which we wrap our entire app within:

<KeyboardProvider statusBarTranslucent navigationBarTranslucent>

I know this might be related to the StatusBar, so thought I'd include that.

Repo for reproducing

N/A, sorry! Can try and create a new repo if absolutely required.

To Reproduce

Expected behavior
I expect the height value returned by useReanimatedKeyboardAnimation to match the height of the keyboard.

Screenshots
(Above)

Smartphone (please complete the following information):

Tested on a Pixel 5 (screenshot). But I see this on a Pixel 7 and 2 also.

  • Desktop OS: MacOS 14.5
  • Device: Pixel 5
  • OS: API 34
  • RN version: 0.73.4
  • RN architecture: old (I think)
  • JS engine: Hermes
  • Library version: 1.12.6

Additional context
Just a thanks for maintaining this library :). If I can provide more info just ask!

@kirillzyusko
Copy link
Owner

Hey @mattlennon3

Maybe it's because of this PR 97d504d?

Prior to this fix all movement inside navigation bar was considered as a non keyboard movement (i. e. if keyboard was shown for let's say 10px and navigation bar translucent, then my hook returned 0).

Can you tell me how do you handle translucency of navigationBar in your code? Do you just set it to translucent and then you are adding a fixed padding to all screens?

If I understand the problem correctly, then you need to change your code to something like this:

const extra = insets.bottom + extraHeight; // no more Platforms check 😎 

Let me know if it helps or not, and if yes then I'll be happy to elaborate more on why it has been changed and why it works in such way now 👀

@kirillzyusko kirillzyusko added the 🤖 android Android specific label Jul 17, 2024
@mattlennon3
Copy link
Author

Hey @kirillzyusko, thanks so much for the fast reply!

I think removing that check has fixed it. I can remove some magic numbers that I was using as a workaround before I raised this issue too! 🙏

Hmm, I think we use this for navigationBar and statusBar config:

const statusBarDefaults = {
  navigationBarColor: '#ffffff00',
  statusBarColor: 'transparent',
  statusBarStyle: 'dark',
  statusBarTranslucent: true,
} as const;

Are any of these values working against me here?

I notice internally we do indeed have an extra bit of bottom padding on every screen that pushes the buttons up even further. But this is existing. I might need to reduce that on smaller devices, but that's a "me" problem :).

I see, so before, the keyboard height was actually not including the navbar height at the bottom, but now it is? So adding insets to android will give me the correct height?

Thanks again for your reply.

@kirillzyusko
Copy link
Owner

Are any of these values working against me here?

No, everything is okay here 🙂

I see, so before, the keyboard height was actually not including the navbar height at the bottom, but now it is?

Yeah, this is something that should be fixed in the first library version. Because without this fix you need to write a conditional code to handle bottom padding. But with this fix I unified the approach and now it works in the same way on both iOS and Android.

So adding insets to android will give me the correct height?

Yes.

Thanks again for your reply.

My pleasure 😊 Can I close the issue? 👀

@kirillzyusko kirillzyusko added the question You wanted to clarify something about the usage of the library or have a question about something label Jul 18, 2024
@mattlennon3
Copy link
Author

Great, thanks so much. I'll close it down. Have a nice day! 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🤖 android Android specific question You wanted to clarify something about the usage of the library or have a question about something
Projects
None yet
Development

No branches or pull requests

2 participants