react-native: Dimensions.get('window').height is sometimes wrong on Android

React Native version: 0.61.4

  System:
    OS: macOS 10.15.1
    CPU: (8) x64 Intel(R) Core(TM) i7-8569U CPU @ 2.80GHz
    Memory: 911.19 MB / 16.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 10.16.0 - /usr/local/bin/node
    Yarn: 1.19.1 - /usr/local/bin/yarn
    npm: 6.11.3 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  SDKs:
    iOS SDK:
      Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1
    Android SDK:
      API Levels: 23, 26, 27, 28
      Build Tools: 23.0.3, 28.0.3
      System Images: android-23 | Android TV ARM EABI v7a, android-23 | Android TV Intel x86 Atom, android-23 | Android Wear ARM EABI v7a, android-23 | Android Wear Intel x86 Atom, android-23 | Intel x86 Atom, android-23 | Intel x86 Atom_64, android-23 | Google APIs ARM EABI v7a, android-23 | Google APIs Intel x86 Atom, android-23 | Google APIs Intel x86 Atom_64, android-26 | Google APIs Intel x86 Atom, android-26 | Google Play Intel x86 Atom, android-27 | Google APIs Intel x86 Atom, android-27 | Google Play Intel x86 Atom, android-28 | Intel x86 Atom, android-28 | Intel x86 Atom_64, android-28 | Google Play Intel x86 Atom_64
  IDEs:
    Android Studio: 3.5 AI-191.8026.42.35.5791312
    Xcode: 11.2.1/11B500 - /usr/bin/xcodebuild
  npmPackages:
    react: 16.9.0 => 16.9.0
    react-native: 0.61.4 => 0.61.4
  npmGlobalPackages:
    create-react-native-module: 0.11.1

Steps To Reproduce

The React Native docs state that “For Android the window dimension will exclude the size used by the status bar (if not translucent) and bottom navigation bar”. Based on that logic, Dimensions.get(‘screen’).height - Dimensions.get(‘window’).height should return the height of the soft menu bar, but it returns the wrong value for some Android devices. On Android, the result of screen and window height difference should be the height of the soft menu bar right, so Dimensions.get('screen').height - Dimensions.get('window').height.

On Pixel 3 (Android 9) and Samsung S9 (Android 9), I get back the difference as 48 which seems to be correct on the UI when testing. However, on OnePlus 6 (Android 9), I get back the difference as 78 which is wrong (should be 48 as well).

To fix this issue, I’ve used the following library https://github.com/Sunhat/react-native-extra-dimensions-android which returns the correct value of 48 for the difference on the OnePlus 6.

Past similar issues

There was this issue https://github.com/facebook/react-native/issues/4934 open for a long time that was closed, even though this is this still is a problem. In that thread, the poster is also using a one plus device, encountering the same issue.

Describe what you expected to happen:

Dimensions.get('screen').height - Dimensions.get('window').height should return the correct value, 48 on OnePlus 6 as well.

I’m wondering if React Native should have an API for getting the soft menu bar height, instead of trusting the difference calculation of window and screen height.

Snack, code example, screenshot, or link to a repository:

Dimensions.get('window').height should return the correct value. OnePlus devices are calculating something extra to the window height.

On OnePlus 6:

Dimensions.get('screen').height: 868.5714285714286
Dimensions.get('window').height: 790.4761904761905

difference: 78.095 (should be 48, which is the soft menu bar height)

On Samsung Galaxy S9:

Dimensions.get('screen').height: 740
Dimensions.get('window').height: 692

difference: 48 (correct, soft menu bar height)

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 14
  • Comments: 17 (5 by maintainers)

Most upvoted comments

This issue is 5 years old and its really big deal, it leads to broken UIs in various widely used devices. @cpojer any chance this can get some attention? I would make a PR but sadly I can’t reproduce the bug since I don’t have a device to do so.

Still the same issue with some Huawei phones, pixel phones, etc… Dimensions and StatusBar bugs together makes it virtually impossible to get the actual screen height when manual heights must be calculated.

For instance, on a Huawei phone, this is the window vs screen height dimensions.

window: {“fontScale”: 1, “height”: 713, “scale”: 3, “width”: 360}

screen: {“fontScale”: 1, “height”: 780, “scale”: 3, “width”: 360}

Status Bar: 27

where’s the 67 pixels that are missing coming from?

Funny thing is that safe-area-context reports the same values: {“frame”: {“height”: 713, “width”: 360, “x”: 0, “y”: 27}, “insets”: {“bottom”: 40, “left”: 0, “right”: 0, “top”: 27}}

Did you try to use Dimensions.get(“screen”).height instead of Dimensions.get(“window”).height ?

It fixes my issue on Google Pixel 4a.

Confirm on several Huawei devices (P30, P20) and some Samsung devices (A30, A40) and at least on Nexus 5X emulator.

It looks like Dimensions.get(‘window’).height is based on content of current screen, but I not so sure about this.