Skip to content
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

The library doesn't support edge-to-edge #97

Closed
zoontek opened this issue Oct 30, 2024 · 9 comments · Fixed by #101
Closed

The library doesn't support edge-to-edge #97

zoontek opened this issue Oct 30, 2024 · 9 comments · Fixed by #101
Labels
Android bug Something isn't working

Comments

@zoontek
Copy link

zoontek commented Oct 30, 2024

Hello again! 🏓

I have a bad news, react-native-edge-to-edge is not at fault at all 😬

Having extra themes will be a nice touch to avoid the initial system bars blink (which is only visible if there's no splash screen, as applyEdgeToEdge will probably be called before you app can switch from your BootTheme to AppTheme)

To reproduce, I used a blank app with [email protected], as I was not able to quickly understand where are the styles.xml and MainActivity.kt on this repository example app 😅
I didn't installed react-native-edge-to-edge as I want to reproduction to be as small as possible.

It breaks immediately when I set WindowCompat.setDecorFitsSystemWindows(window, false). That's the first step of how to enable edge-to-edge.

This is of course used by react-native-edge-to-edge, but also by:

And probably a lot of other libs.

The reproduction can be found here. And these changes are enough to recreate the issue.

Screenshot 2024-10-30 at 18 33 12
@zoontek
Copy link
Author

zoontek commented Oct 30, 2024

Did a quick check, the issue exists because you have to handle insets

Here, it's super buggy and all and I harcoded the value, but the tab bar has (I think) the correct height:

Screenshot 2024-10-30 at 19 17 08

The react-native-safe-area-context codebase could probably help you.

@okwasniewski
Copy link
Collaborator

@zoontek Thanks for your investigation! I will handle it in the library 🙌

@okwasniewski okwasniewski added bug Something isn't working Android labels Oct 30, 2024
@okwasniewski
Copy link
Collaborator

I got this to work!

@zoontek As you are more familiar with the topic, what's a reliable way of checking if edge to edge is enabled? It's the last thing Im struggling with

CleanShot 2024-10-30 at 22 06 19@2x

@zoontek
Copy link
Author

zoontek commented Oct 30, 2024

@okwasniewski That's the tricky part. As I mentionned in this message, there's no way to properly detect edge-to-edge (see this tweet too). That's why we went for a common library, because at least this is something that could be detected.

Are you performing different computation if it's enabled or not (maybe you can inset in all cases, as it's 0 when disabled)?

If yes, add react-native-is-edge-to-edge as a dependency (it's extra lightweight), add a prop / option (navigationBarTranslucent, for example). Then follow the method in the README:

import { controlEdgeToEdgeValues, isEdgeToEdge } from "react-native-is-edge-to-edge";

const EDGE_TO_EDGE = isEdgeToEdge();

function TabBar({ navigationBarTranslucent = false }) {
  if (__DEV__) {
    controlEdgeToEdgeValues({ navigationBarTranslucent });
  }

  return (
    <NativeTabBar
      navigationBarTranslucent={EDGE_TO_EDGE || navigationBarTranslucent}
      // …
    />
  );
}

This way, it will just work out-of-the-box for people using react-native-edge-to-edge, and the others will still be able to set navigationBarTranslucent={true} if they want.

@okwasniewski okwasniewski linked a pull request Oct 30, 2024 that will close this issue
@okwasniewski
Copy link
Collaborator

Thanks for the tip!

Looks like this check on the native side val isSystemBarTransparent = window?.navigationBarColor == Color.TRANSPARENT might be enough for this library as I need to "stretch" the navigation view only when the navigationBarColor is transparent.

I've tested it with your library (enabled and disabled) and this PR: #101 should address this issue.

@zoontek
Copy link
Author

zoontek commented Oct 30, 2024

@okwasniewski This is really fragile. On Android < 10, window?.navigationBarColor != Color.TRANSPARENT, even in edge-to-edge (it's a semi opaque white or black - Color.argb(0xe6, 0xFF, 0xFF, 0xFF) or Color.argb(0x80, 0x1b, 0x1b, 0x1b), depending on the OS versions)

Even on newer versions, buttons based navigation isn't transparent:

Screenshot 2024-10-31 at 00 00 48

@zoontek
Copy link
Author

zoontek commented Oct 30, 2024

Note that if you don't want an extra JS dependency, you can achieve package detection in Kotlin too (Class.forName is handled by Proguard):

val isSystemBarTransparent = try {
  Class.forName("com.zoontek.rnedgetoedge.EdgeToEdgePackage")
  true
} catch (exception: ClassNotFoundException) {
  window?.navigationBarColor == Color.TRANSPARENT // fallback to best-effort detection
}

EDIT: the class check could be a val in a companion object, it only needs to be checked once in app lifecycle:

companion object {
  val EDGE_TO_EDGE = try {
    Class.forName("com.zoontek.rnedgetoedge.EdgeToEdgePackage")
    true
  } catch (exception: ClassNotFoundException) {
    false
  }
}

fun yourFn() {
  // fallback to best-effort detection
  val isSystemBarTransparent = EDGE_TO_EDGE || window?.navigationBarColor == Color.TRANSPARENT
  
  //

@okwasniewski
Copy link
Collaborator

Thanks @zoontek this check in Kotlin is perfect!

Going to add it 👍🏻

@okwasniewski
Copy link
Collaborator

okwasniewski commented Oct 31, 2024

Thanks for your support @zoontek I also added page in docs describing to install your library in order to enable the support: https://okwasniewski.github.io/react-native-bottom-tabs/docs/guides/edge-to-edge-support.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Android bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants