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

Make the navigation bar and status bar transparent (edge-to-edge) #4547

Open
MathisP75 opened this issue Aug 1, 2024 · 5 comments
Open

Make the navigation bar and status bar transparent (edge-to-edge) #4547

MathisP75 opened this issue Aug 1, 2024 · 5 comments
Labels
enhancement New feature or request

Comments

@MathisP75
Copy link

MathisP75 commented Aug 1, 2024

Is your feature request related to a problem? Please describe.
Both the navigation bar and the status bar are solid colors and do not allow for other elements to go under them, making the application feel less polished.

Describe the solution you'd like
Making the application display edge-to-edge content, as described here: https://developer.android.com/develop/ui/views/layout/edge-to-edge

Describe alternatives you've considered, if any
Not applicable.

Additional context
Example of an app handling edge-to-edge incorrectly (notice how the side menu goes under the navigation bar and the status bar): Screenshot_20240801-192313.png

Example of an app handling edge-to-edge correctly (notice how the side menu goes under both the navigation bar and the status bar, since they are truly transparent): Screenshot_20240801-192429.png

@MathisP75 MathisP75 added the enhancement New feature or request label Aug 1, 2024
@jpelgrom
Copy link
Member

jpelgrom commented Aug 2, 2024

Unfortunately this isn't as easy as you might think because of the WebView. Last time I tried the problem was that information about insets wasn't set correctly on the WebView, making it impossible for the frontend to adapt. That means content will end up behind the system navigation, which is especially problematic when using button navigation or when you have a tall status bar due to a camera/cutout. It looks like the bug is still unresolved: https://issuetracker.google.com/issues/40699457.

(I thought we already had an issue for this, but can't find it.)

@MathisP75
Copy link
Author

Ah well that sucks, it would have been neat. Let's hope Google does something about it.

@Gregman-js
Copy link

Gregman-js commented Jan 19, 2025

What do you think about passing this inset values from android activity to webview on page load?
I created a quick demo in Android Compose:

Scaffold (modifier = Modifier.fillMaxSize()) { padding ->
    AndroidView(
        factory = { context ->
            WebView(context).apply {
                settings.javaScriptEnabled = true
                webViewClient = object : WebViewClient() {
                    override fun onPageFinished(view: WebView?, url: String?) {
                        super.onPageFinished(view, url)
                        val safeInsetTop = (padding.calculateTopPadding().value)
                        val safeInsetBottom = (padding.calculateBottomPadding().value)
                        val safeAreaJs = """
                        document.documentElement.style.setProperty('--android-safe-area-inset-top', '${safeInsetTop}px');
                        document.documentElement.style.setProperty('--android-safe-area-inset-bottom', '${safeInsetBottom}px');
                    """.trimIndent()
                        evaluateJavascript(safeAreaJs, null)
                    }
                }
            }
        },
        update = { webView ->
            webView.loadUrl("http://10.0.2.2:8000")
        },
    )
}

In above snippet we can see that Scaffold component (edge-to-edge) give us padding property (our insets) and we are executing JS after page load that sets css properties.
Then HA page instead of relying on env() can have custom property that works on both android and ios.

:root {
  --insets-top: var(--android-safe-area-inset-top, env(safe-area-inset-top));
  --insets-bottom: var(--android-safe-area-inset-bottom, env(safe-area-inset-bottom));
}
.main {
      padding-top: var(--insets-top);
}
.bottom {
   position: fixed;
   bottom: 0;
   padding-bottom: var(--insets-bottom);
   background-color: white;
   display: block;
   width: 100%;
  }

Below we can see that text have proper padding on top and bottom of screen

Image Image

@jpelgrom
Copy link
Member

jpelgrom commented Jan 21, 2025

This looks a bit hacked together to me but considering how the WebView still doesn't do inset support correctly (it now kinda works on first load, but breaks after navigation) if the frontend team is OK, I think we can consider it as well.

Not as easy as you might think however because HA/frontend version is decoupled from the app and users might have multiple servers on different HA versions.

@Gregman-js
Copy link

I created this PR with your comment in mind.
So WebView will be renedered under navigation bar only if below condition is matched (version value will depend on this relese)

serverManager.getServer()?.version?.isAtLeast(2024, 1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants