Open joeporpeglia opened 11 months ago
Please correct me if I'm wrong, but i believe this is the intended behavior, @joeporpeglia.
In React Native, useWindowDimensions
provides the dimensions of the window (or viewport), which differ from the full screen dimensions. This difference is particularly noticeable in cases where translucent or hidden system UI elements, like the navigation bar, are present.
Internally, useWindowDimensions
utilizes the DisplayMetrics
object retrieved from context.getResources().getDisplayMetrics()
. This method in Android does exclude the navigation bar in its calculations. It returns metrics based on the current display metrics, representing the screen area available to your application. This typically exclude system UI elements such as the navigation bar.
Currently, there isn't a dedicated hook in React Native for directly accessing the full "Screen" dimensions. However, in situations where you need to consider the entire screen size - particularly in apps that use a translucent navigation bar or operate in edge-to-edge mode - I suggest using the following approach:
import { Dimensions } from 'react-native';
const screenWidth = Dimensions.get('screen').width;
const screenHeight = Dimensions.get('screen').height;
This method will provide you with the full dimensions of the screen, inclusive of the areas covered by system UI elements, which is crucial for accurate layout and design in such specific scenarios.
cc @cortinico As a side note, I believe adding a dedicated hook for screen dimensions could be beneficial for users. I'm considering creating such a hook in the core library, tentatively named useScreenDimensions. What do you think?
Another side note: I saw that in a previous issue, someone suggested that if the app is in full-screen mode on Android, the window height should include the status bar and bottom navigation bar.
We could potentially find a way to implement this, but I'm concerned about the potential for unexpected values due to the addition of the status bar and bottom navigation bar.
If you think about it, including the status bar and bottom navigation bar in the window size essentially yields the same result as Dimensions.get('screen')
. Perhaps the best approach is to leave it up to the developers to decide when to use Dimensions.get('screen')
or Dimensions.get('window')
.
@gedeagas that's fair if this is the expected behavior for android. It's surprising though, given useWindowDimensions
includes the status bar and home indicator on iOS. Does the screen vs window distinction apply to iOS or is that specific to Android?
@gedeagas that's fair if this is the expected behavior for android. It's surprising though, given
useWindowDimensions
includes the status bar and home indicator on iOS. Does the screen vs window distinction apply to iOS or is that specific to Android?
@joeporpeglia In iOS, windowSize
is determined by the bounds of the key window (mainWindow.bounds.size
), or, as a fallback, by the screen size. This measurement represents the full dimensions of the window or screen, encompassing areas that may be underlapped by system elements. Crucially, it does not automatically exclude regions occupied by features like the home indicator or the notch.
The behavior on iOS differs notably because the interface typically lacks a dedicated bottom navigation bar, unlike some Android devices. In iOS devices with a home button, there is no persistent UI element for bottom navigation. On iPhone X and later models, the home indicator is designed to float over app content, unless managed explicitly with the SafeAreaView component.
I'm also having the same problem. I've used useWindowDimensions, Dimensions.get('screen').height, or Dimensions.get('window').height, but it doesn't work. Please help me solve this problem. ![Uploading Screen Shot 2023-12-19 at 18.22.23.png…]()
@chienvuvan99 Hi, could you please provide more details about the issue you're encountering? Unfortunately, I'm unable to view the screenshot you've mentioned.
To better assist you, it would be greatly helpful if you could outline the steps to reproduce the issue or share a reproducible demo, similar to what @joeporpeglia has provided.
@gedeagas Hi. I have a list of videos, each item in the list has the width and height of the screen, but on Android the height is not correct. I have used useWindowDimensions, Dimensions.get('screen').height, or Dimensions.get('window').height but they do not work.
@gedeagas I'm actually seeing inconsistent dimensions when testing this on different android devices. On a Pixel 5 emulator the status bar height is included in useWindowDimensions().height
, but on my Pixel 5 device it's not. Both are running Android 12, so it's unclear what could be causing the discrepancy here.
I ran the same reproducer on my device and this was the rendered output:
I am having exactly the same issue. Testing on a physical Pixel 4a and an emulated Pixel 4XL (both with Android 13) yields different results for height. one includes the statusbar height in the value, the other one does not. I tried the useWindowDimensions hook and also Dimensions.get('window') as well as Dimensions.get('screen').
"react": "18.2.0", "react-native": "0.73.4", "expo": "^50.0.6",
Same issue.
On react-native 0.74.1 it still happens
Also one aspect of this issue is that the reported window height doesn't change on an Android device when you set the status bar translucent
, while according to the documentation at https://reactnative.dev/docs/dimensions it says "For Android the window dimension will exclude the size used by the status bar (if not translucent) and bottom navigation bar". So it should be excluded if not translucent, and included if it is translucent, which makes sense since the zero point of the drawable area changes according to the translucency.
And then another aspect of this is the fact others have mentioned that it depends on the device whether the status bar area is included in the window height or not, which makes it very hard to make calculations based on the window height since you don't know if it includes the status bar or not.
I keep stumbling upon this issue
Dimensions.get('screen').height
it is
Unfortunately, this is not responsive.
Same problem with galaxy fold 5, when the phone is folded useWindowDimensions.height includes the statusbar's height and when the phone is unfolded it does not. Is there, a work arround for this ? (using Dimensions to get the height does not rerender views).
@hamzawii I had to implement a custom useWindowDimensions
hook that uses the height/width of a root View
Description
The window height doesn't include the navigation bar height when it's displayed as "translucent". This also occurs if you enable edge-to-edge mode, which similarly shows the app UI under the system UI.
Steps to reproduce
Install and run the reproducer project
React Native Version
0.73.0
Affected Platforms
Runtime - Android
Output of
npx react-native info
Stacktrace or Logs
Reproducer
https://github.com/joeporpeglia/rn-android-window-dimensions-reproducer
Screenshots and Videos
In the screenshots below the height of the blue view is set to
useWindowDimensions().height
.Navigation bar height is excluded on all android devices I tested
Status bar height is excluded on Pixel 5 device