-
Notifications
You must be signed in to change notification settings - Fork 24.7k
Proposal: Edge-to-edge support #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
base: main
Are you sure you want to change the base?
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
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 <bartlomiej.bloniarz@swmansion.com>
…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 <bartlomiej.bloniarz@swmansion.com>
…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 <bartlomiej.bloniarz@swmansion.com>
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? |
@alanleedev Given all of that, keeping the opt-in flag is the better option. I will rollback this part too when I'm home. |
# Conflicts: # packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/ProjectUtils.kt # packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/PropertyUtils.kt # packages/react-native-info/src/info.ts # packages/react-native/Libraries/Modal/Modal.js # packages/react-native/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultReactHost.kt # packages/react-native/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultReactNativeHost.kt # packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/WindowUtil.kt # packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterActivity.kt # Conflicts: # packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.kt # Conflicts: # packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/appearance/AppearanceModule.kt # packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java
aa27f8d
to
0f0d2b1
Compare
@alanleedev I added back the
The navigation bar behavior is similar to the one enforced on Android 15:
We could add a |
Summary:
Following our discussion on Discord, here's the WIP of a proposal to add edge-to-edge support directly in core. This is based on a few things:
A new gradle property:
edgeToEdgeEnabled
This could be changed by the user (similar to
hermesEnabled
/newArchEnabled
) and should befalse
by default (for the moment), and is usable by third-party libraries:Appearance.isEdgeToEdge()
Similar to the native side detection, this PR also add JS side detection.
This is useful for packages that doesn't rely on native code (for example, it will be used by
react-native-is-edge-to-edge
to detect eitherreact-native-edge-to-edge
install or if edge-to-edge is enabled in core).Update
StatusBar
props behaviorIn order to keep edge-to-edge working, it's mandatory to disable some props behavior:
backgroundColor
andtranslucent
have no effect when edge-to-edge is enabled (setBackgroundColor
/setTranslucent
methods too)What's missing
Dimensions
module to includes status bar and navigation bar insets in window size computationChangelog:
[ANDROID] [ADDED] Edge-to-edge support
Test Plan:
Run the example app: