kirillzyusko / react-native-keyboard-controller

Keyboard manager which works in identical way on both iOS and Android
https://kirillzyusko.github.io/react-native-keyboard-controller/
MIT License
1.62k stars 67 forks source link

KeyboardAvoidingView doesn't work as intended on Android 10 #398

Closed breakingrobot closed 6 months ago

breakingrobot commented 6 months ago

Describe the bug On an Android 10 React Native app using a multi-step form with two screens that include an autofocused TextInput, any router.navigate or router.push will succeed but the following will happen

Repo for reproducing https://github.com/breakingrobot/react-native-keyboard-controller/tree/android-10-bug

To Reproduce Steps to reproduce the behavior:

  1. Run an emulator with Android SDK <=29 (Android 10 and lower)
  2. Build the example app from my fork
  3. Go to Example 14. Keyboard Avoiding View
  4. Press Submit
  5. Go back and retry

Expected behavior Behavior that exhibit any Android devices with Android 11 and higher :

Screenshots

Android 10 - SDK 29

https://github.com/kirillzyusko/react-native-keyboard-controller/assets/15056336/ff1dc4ee-350c-4770-92e3-56938bcc2c82

Android 14 - SDK 34

https://github.com/kirillzyusko/react-native-keyboard-controller/assets/15056336/59bd57d0-6b80-4000-8f62-10089fc42429

Smartphone (please complete the following information):

kirillzyusko commented 6 months ago

@breakingrobot Interesting! I thought it could be fixed in https://github.com/kirillzyusko/react-native-keyboard-controller/pull/391 but it looks like you are using latest version and if the issues is reproducible - it means that it's something else.

On your video I see, that on Android 14 keyboard starts to hide, but then appears again, while on Android 10 it always stays on the screen.

I'll look into the problem, but as a potential workaround I could suggest you to manually close keyboard before navigating to the next screen (KeyboardController.dismiss()) and do autoFocus with some delay, like:

useEffect(() => {
  setTimeout(() => textInputRef.current.focus(), 250);
}, []);

I think it should do the trick! But I'll try to allocate some time and look into the problem 👀

breakingrobot commented 6 months ago

@kirillzyusko Thanks for your quick answer, just to let you know I had a workaround with KeyboardController.dismiss()

I then tried with delaying focus with a textInputRef exactly like your code snippet and it alone solved the issue without KeyboardController.dismiss()

Using expo-router or react-navigation useFocusEffect :

useFocusEffect(
    useCallback(() => {
      setTimeout(() => inputRef?.current?.focus(), 250);
    }, []),
  );

This seems to do the trick right now, again thank you for your time to look into the problem!