-
Notifications
You must be signed in to change notification settings - Fork 24.8k
Fix Dimensions window values on Android < 15 #47554
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
Conversation
Why would StatusBar backgroundColor prop have no effect in edge to edge? I have cases where I use a semi transparent background in edge to edge mode. |
@janicduplessis Setting status bar color (
Instead, you can still put an empty |
@zoontek Would there be a way to avoid adding |
@alanleedev Would you be OK in using |
To enable edge-to-edge in SDK < 35 Android’s recommendation is to call enableEdgeToEdge on ComponentActivity. Why isn’t that the approach taken here? And shouldn’t |
@grahammendick Because |
@zoontek Most people that use React Native don't use the React Native |
@grahammendick Android doesn't provide a way to properly detect if edge-to-edge is enabled, so even if let's say, the user call Add the facts that:
public fun Window.enableEdgeToEdge() {
val isDarkMode = ContextUtils.isDarkMode(context)
WindowCompat.setDecorFitsSystemWindows(this, false)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
isStatusBarContrastEnforced = false
isNavigationBarContrastEnforced = true
}
statusBarColor = Color.TRANSPARENT
navigationBarColor =
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> Color.TRANSPARENT
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !isDarkMode -> Color.argb(0xe6, 0xFF, 0xFF, 0xFF)
else -> Color.argb(0x80, 0x1b, 0x1b, 0x1b)
}
WindowInsetsControllerCompat(this, this.decorView).run {
isAppearanceLightNavigationBars = !isDarkMode
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
attributes.layoutInDisplayCutoutMode =
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
else -> WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
}
}
} And it's hard to justify going that way. |
React Native can add a |
@grahammendick Even with that, you still need to have this function in RN to apply edge-to-edge on Regarding using |
I'm not really the right person to review this as I don't have that extensive knowledge on Android. |
...e-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/ProjectUtils.kt
Outdated
Show resolved
Hide resolved
private fun Window.statusBarShow() { | ||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { | ||
private fun Window.statusBarShow(isEdgeToEdge: Boolean) { | ||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !isEdgeToEdge) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Always was hesitant to ask, but now I feel like it's a right time 🙂
From what I remember StatusBar
management uses some deprecated methods for managing its properties. As a result it may break some animations driven by WindowInsetsAnimationCompat.Callback
.
To overcome this problem I had to create own module based on WindowInsetsControllerCompat
class and monkey-patch JS module afterward.
This is directly not related to this PR, but I'd like to discuss a possibility to rewrite StatusBar management to a new/modern API 🙌 (whether FB team is open to it and if not then what blocks/prevents that).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kirillzyusko We can discuss about it if we have bit more details on the change you wan to make. There is also react-native-edge-to-edge SystemBars. So may need to check if it would be better to update that instead.
packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/WindowUtil.kt
Outdated
Show resolved
Hide resolved
I also agree with @zoontek here. Theoretically we can listen to root view insets and based on that decide whether we are in edge-to-edge mode or not. But in my opinion it will add more code complexity and at some point of time there will appear a situations, when something not working etc. The case that you described it a simple misconfiguration between two modules (user-defined code and RN). and such misconfiguration happens relatively frequently now - that's why @zoontek created I think the best way here would be to write a blog post explaining for people, that if they used |
packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt
Outdated
Show resolved
Hide resolved
e101925
to
90ad847
Compare
…isNavigationBarTranslucentAndroid (#6732) ## Summary Similar to [the PR](software-mansion/react-native-screens#2464) I opened on the `react-native-screens` repository (I highly recommend to read the discussion there to understand the motivation behind this), this PR detects if the user enabled edge-to-edge and act accordingly: `useAnimatedKeyboard` are ignored, set to `true` automatically. If those are set, a warning is logged: > `isStatusBarTranslucentAndroid` and `isNavigationBarTranslucentAndroid` values are ignored when `using react-native-edge-to-edge` It at some point [this proposal](facebook/react-native#47554) lands in core, `react-native-is-edge-to-edge` will be updated to support both the library and the core edge-to-edge flag, making the transition seamless for the users. ## Test plan - Install [react-native-edge-to-edge](https://github.com/zoontek/react-native-edge-to-edge) in the example app. - Don't set `isStatusBarTranslucentAndroid` / `isNavigationBarTranslucentAndroid`, or set them to something else than `true` --------- Co-authored-by: Bartłomiej Błoniarz <[email protected]>
…isNavigationBarTranslucentAndroid (#6732) ## Summary Similar to [the PR](software-mansion/react-native-screens#2464) I opened on the `react-native-screens` repository (I highly recommend to read the discussion there to understand the motivation behind this), this PR detects if the user enabled edge-to-edge and act accordingly: `useAnimatedKeyboard` are ignored, set to `true` automatically. If those are set, a warning is logged: > `isStatusBarTranslucentAndroid` and `isNavigationBarTranslucentAndroid` values are ignored when `using react-native-edge-to-edge` It at some point [this proposal](facebook/react-native#47554) lands in core, `react-native-is-edge-to-edge` will be updated to support both the library and the core edge-to-edge flag, making the transition seamless for the users. ## Test plan - Install [react-native-edge-to-edge](https://github.com/zoontek/react-native-edge-to-edge) in the example app. - Don't set `isStatusBarTranslucentAndroid` / `isNavigationBarTranslucentAndroid`, or set them to something else than `true` --------- Co-authored-by: Bartłomiej Błoniarz <[email protected]>
…isNavigationBarTranslucentAndroid (#6732) ## Summary Similar to [the PR](software-mansion/react-native-screens#2464) I opened on the `react-native-screens` repository (I highly recommend to read the discussion there to understand the motivation behind this), this PR detects if the user enabled edge-to-edge and act accordingly: `useAnimatedKeyboard` are ignored, set to `true` automatically. If those are set, a warning is logged: > `isStatusBarTranslucentAndroid` and `isNavigationBarTranslucentAndroid` values are ignored when `using react-native-edge-to-edge` It at some point [this proposal](facebook/react-native#47554) lands in core, `react-native-is-edge-to-edge` will be updated to support both the library and the core edge-to-edge flag, making the transition seamless for the users. ## Test plan - Install [react-native-edge-to-edge](https://github.com/zoontek/react-native-edge-to-edge) in the example app. - Don't set `isStatusBarTranslucentAndroid` / `isNavigationBarTranslucentAndroid`, or set them to something else than `true` --------- Co-authored-by: Bartłomiej Błoniarz <[email protected]>
Hey, I want to rekindle the discussion here. Is progress here blocked & we settled with putting source of truth for edge-to-edge in third-party-library or is it still planned to land this proposal eventually in core? |
This pull request has been reverted by b4dcc98. |
@zoontek we had to revert this because of integration issues |
@cortinico Is there something that could be done? |
We're looking inot it. We'll keep you in the loop if there is anything needed on your end 👍 |
Summary: This PR (initially created for edge-to-edge opt-in support, rebased multiple times) fixes the `Dimensions` API `window` values on Android < 15, when edge-to-edge is enabled. Currently the window height doesn't include the status and navigation bar heights (but it does on Android >= 15): <img width="300" alt="Screenshot 2025-06-27 at 16 23 02" src="https://github.com/user-attachments/assets/c7d11334-9298-4f7f-a75c-590df8cc2d8a" /> Using `WindowMetricsCalculator` from AndroidX: <img width="300" alt="Screenshot 2025-06-27 at 16 34 01" src="https://github.com/user-attachments/assets/7a4e3dc7-a83b-421b-8f6d-fd1344f5fe81" /> Fixes facebook#47080 ## Changelog: [Android] [Fixed] Fix `Dimensions` `window` values on Android < 15 when edge-to-edge is enabled Test Plan: Run the example app on an Android < 15 device. Rollback Plan: Differential Revision: D77906644 Pulled By: alanleedev
Summary: This PR (initially created for edge-to-edge opt-in support, rebased multiple times) fixes the `Dimensions` API `window` values on Android < 15, when edge-to-edge is enabled. Currently the window height doesn't include the status and navigation bar heights (but it does on Android >= 15): <img width="300" alt="Screenshot 2025-06-27 at 16 23 02" src="https://github.com/user-attachments/assets/c7d11334-9298-4f7f-a75c-590df8cc2d8a" /> Using `WindowMetricsCalculator` from AndroidX: <img width="300" alt="Screenshot 2025-06-27 at 16 34 01" src="https://github.com/user-attachments/assets/7a4e3dc7-a83b-421b-8f6d-fd1344f5fe81" /> Fixes #47080 ## Changelog: [Android] [Fixed] Fix `Dimensions` `window` values on Android < 15 when edge-to-edge is enabled Pull Request resolved: #47554 Test Plan: Run the example app on an Android < 15 device. Rollback Plan: Reviewed By: cortinico Differential Revision: D77547628 Pulled By: alanleedev fbshipit-source-id: 9d841f642d5b7ef3294dfbf3868137087a672ad6
This reverts commit 9c4da7b.
Hey @zoontek
Could you look into it? cc @alanleedev for visibility |
@cipolleschi @alanleedev That's because the method is called with a non-UI context and this doesn't work on Android < R. To fix this, in this PR, replace this line: react-native/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java Line 868 in 2321ae1
with: DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(getContext()); and this line (to prevent crash on orientation change): react-native/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java Line 991 in 2321ae1
with: DisplayMetricsHolder.initDisplayMetrics(getContext()); UiContext.fix.mp4 |
Summary: Pull Request resolved: facebook#52481 This PR (initially created for edge-to-edge opt-in support, rebased multiple times) fixes the `Dimensions` API `window` values on Android < 15, when edge-to-edge is enabled. Currently the window height doesn't include the status and navigation bar heights (but it does on Android >= 15): <img width="300" alt="Screenshot 2025-06-27 at 16 23 02" src="https://github.com/user-attachments/assets/c7d11334-9298-4f7f-a75c-590df8cc2d8a" /> Using `WindowMetricsCalculator` from AndroidX: <img width="300" alt="Screenshot 2025-06-27 at 16 34 01" src="https://github.com/user-attachments/assets/7a4e3dc7-a83b-421b-8f6d-fd1344f5fe81" /> Fixes facebook#47080 ## Changelog: [Android] [Fixed] Fix `Dimensions` `window` values on Android < 15 when edge-to-edge is enabled Pull Request resolved: facebook#47554 Test Plan: Run the example app on an Android < 15 device. Rollback Plan: Reviewed By: cortinico Differential Revision: D77906644
@zoontek
|
@alanleedev Yes, tried it on an Android 7 emulator (check the video). Isn't the |
@zoontek I tried on Android 7 emulator without the change and it didn't crash for me. |
@alanleedev When I tried it with By passing UI context ( |
@zoontek That is weird, it does not repro for me on my emulator running on ARM based Mac. At least, I don't see any issues with the code fix. I guess we can try to merge and see if we run into any issues in the release branch. |
Summary: Pull Request resolved: #52481 This PR (initially created for edge-to-edge opt-in support, rebased multiple times) fixes the `Dimensions` API `window` values on Android < 15, when edge-to-edge is enabled. Currently the window height doesn't include the status and navigation bar heights (but it does on Android >= 15): <img width="300" alt="Screenshot 2025-06-27 at 16 23 02" src="https://github.com/user-attachments/assets/c7d11334-9298-4f7f-a75c-590df8cc2d8a" /> Using `WindowMetricsCalculator` from AndroidX: <img width="300" alt="Screenshot 2025-06-27 at 16 34 01" src="https://github.com/user-attachments/assets/7a4e3dc7-a83b-421b-8f6d-fd1344f5fe81" /> Fixes #47080 ## Changelog: [Android] [Fixed] Fix `Dimensions` `window` values on Android < 15 when edge-to-edge is enabled Pull Request resolved: #47554 Test Plan: Run the example app on an Android < 15 device. Rollback Plan: Reviewed By: cortinico Differential Revision: D77906644 Pulled By: alanleedev fbshipit-source-id: 121cd6bc4133973f06b28eb9e79c9387ac7070a1
Hey @zoontek Sadly this is still crashing, on release only and on Android 7 only with the following stacktrace:
|
cc @alanleedev |
@zoontek @cortinico I think we may have to rethink this approach.
It is checking for UiContext which is mainly Activity or InputMethodService.
I am not sure why this only happens on release build, why I wasn't getting a crash when testing on Android 7 emulator (build using BUCK) or how the issue was resolved for @zoontek with the fix. But seems like we may need to rethink about how this is handled. |
@cortinico @alanleedev There's probably a race condition between Indeed, we need to rethink the approach. For me, PS: Note that this isn't blocking for |
@cortinico @alanleedev I've been able to reproduce the issue on Android 7, in release mode only (this doesn't occur in debug mode). I switched The fix is here: https://github.com/zoontek/react-native/pull/1/files EDIT: Here is the video. Note that I tested it with and without demo.mp4 |
Could you send this as a PR against facebook/react-native ? |
@cortinico Sure thing, here it is: #52738 |
Summary:
This PR (initially created for edge-to-edge opt-in support, rebased multiple times) fixes the
Dimensions
APIwindow
values on Android < 15, when edge-to-edge is enabled.Currently the window height doesn't include the status and navigation bar heights (but it does on Android >= 15):
Using
WindowMetricsCalculator
from AndroidX:Fixes #47080
Changelog:
[Android] [Fixed] Fix
Dimensions
window
values on Android < 15 when edge-to-edge is enabledTest Plan:
Run the example app on an Android < 15 device.