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

feat: own `useWindowDimensions` hook #468

Closed kirillzyusko closed 3 months ago

kirillzyusko commented 3 months ago

πŸ“œ Description

Implemented own useWindowDimensions hook for Android.

πŸ’‘ Motivation and Context

The problem with default implementation of useWindowDimensions on Android is that it doesn't work well with edge-to-edge mode and you can not retrieve an actual size of the screen. Here is a brief comparison of values captured on my device (Pixel 7 Pro).

Translucent StatusBar:

height: 867.4285888671875 <- own hook
height: 867.4285888671875, y: 0 <- useSafeAreaFrame
height: 891.4285714285714 <- Dimensions.get('screen')
height: 826.2857142857143 <- Dimensions.get('window')

Non translucent StatusBar:

height: 867.4285888671875 <- own hook
height: 826.2857055664062, y: 41.14285659790039 <- useSafeAreaFrame
height: 891.4285714285714 <- Dimensions.get('screen')
height: 826.2857142857143 <- Dimensions.get('window')

So as you can see it doesn't react properly on the case when StatusBar is translucent and reports incorrect values, which later on causes incorrect layout calculation in components like KeyboardAvoidingView or KeyboardAwareScrollView.

Theoretically we could workaround this problem by original useWindowDimensions().height + StatusBar.currentHeight, but everything become trickier when we add translucent navigationBar (+ translucent statusBar):

height: 891.4285888671875 <- own hook
height: 891.4285888671875, y: 0 <- useSafeAreaFrame
height: 891.4285714285714 <- Dimensions.get('screen')
height: 826.2857142857143 <- Dimensions.get('window')

In this case derived value useWindowDimensions().height + StatusBar.currentHeight (867.4285888671875) still will produce incorrect value and all calculations will be broken. So I decided to create own version of the hook which will cover all the cases.

Issue for reference: https://github.com/facebook/react-native/issues/41918

Closes https://github.com/kirillzyusko/react-native-keyboard-controller/issues/434 https://github.com/kirillzyusko/react-native-keyboard-controller/issues/334

πŸ“’ Changelog

JS

Android

πŸ€” How Has This Been Tested?

Tested manually on Pixel 7 Pro (API 34).

Tested on CI via e2e (API 28).

πŸ“Έ Screenshots (if appropriate):

Pixel 7 Pro (Android 14), KeyboardAwareScrollView:

KeyboardAwareScrollView

Before After
telegram-cloud-photo-size-2-5429580266013318443-y telegram-cloud-photo-size-2-5429580266013318444-y

KeyboardAvoidingView

Initial Before After
telegram-cloud-photo-size-2-5429580266013318470-y telegram-cloud-photo-size-2-5429580266013318469-y telegram-cloud-photo-size-2-5429580266013318471-y

πŸ“ Checklist

github-actions[bot] commented 3 months ago

πŸ“Š Package size report

Current size Target Size Difference
144033 bytes 138194 bytes 5839 bytes πŸ“ˆ