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

[Android Q] Transparent navigation bar with extended scaffold #34678

Closed
Zazo032 opened this issue Jun 18, 2019 · 21 comments
Closed

[Android Q] Transparent navigation bar with extended scaffold #34678

Zazo032 opened this issue Jun 18, 2019 · 21 comments
Assignees
Labels
f: material design framework platform-android

Comments

@Zazo032
Copy link
Contributor

Zazo032 commented Jun 18, 2019

In Android Q, when using the new full gesture navigation, if an app has a transparent navigation bar, the gestural navigation area is floating over the app, and no black or white navigation bar is shown.

As stated by Dave Burke: https://twitter.com/davey_burke/status/1126878112170405888

Seems to be an easy addition but right now I didn't manage to make it work. I tried to set transparent navigation bar but it is not working properly as the navigation bar is still black or white (in Android Q). If the navigation bar is enabled, the Scaffold may also need to be extended a bit more so it is shown under de gestures area.

@HansMuller HansMuller added framework f: material design platform-android labels Jun 19, 2019
@bernaferrari
Copy link
Contributor

bernaferrari commented Jun 20, 2019

While this has been a hot topic now, Google is recommending to use transparent navigation bar everywhere, not only in Q. Since users in Q will be able to choose between the new and the old navigation bar, we should just use the entire display for most apps and add a bottom padding to lists.

@shihaohong
Copy link
Contributor

shihaohong commented Aug 1, 2019

This is related to #32748, just adding this in to tie all Android Q issues together

@shihaohong
Copy link
Contributor

shihaohong commented Aug 2, 2019

Actually, I believe removing the bottom navigation bar is already possible with SystemChrome. setEnabledSystemUIOverlays. What you have to do is import package:flutter/services.dart, then call:

SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.top]) // tells app to only show the status bar

The main piece that's missing is how to determine the system gesture window insets, which I'm currently working on

@bernaferrari
Copy link
Contributor

bernaferrari commented Aug 2, 2019

There is a problem. You don't want this:

On Android it's recommended that you keep FAB and etc at relative 16 (i.e. in the safe area) because.. well, as you saw there, you don't know the height of the bar. On iOS, Google has been using absolute 16 because the bar height is always the same.

@gaurav414u
Copy link

gaurav414u commented Aug 27, 2019

Any updates on this?
When do you guys plan to get it fixed and merged?
@shihaohong

@shihaohong
Copy link
Contributor

shihaohong commented Aug 27, 2019

What is the particular ask? It's already currently possible to set a transparent navigation bar using the SystemChrome API

@gaurav414u
Copy link

gaurav414u commented Aug 27, 2019

So, I am able to make the navigation bar transparent but I cannot draw a layout behind the navigation bar.

@shihaohong
Copy link
Contributor

shihaohong commented Aug 31, 2019

I will close this for now, since it seems like it is possible to create a transparent navigation bar that allows the Scaffold to extend behind the Android Q nav bar using SystemChrome.setEnabledSystemUIOverlays.

However, if there seems to be more precise asks, please feel free to file new issues so that we can track individual needs. Every contribution to this issue seems to be asking for slightly different things (ie transparent Android Q nav bar, making the nav bar transparent while still exposing system windows insets regardless of Android SDK version, etc).

Android Q Prep automation moved this from To do to Done Aug 31, 2019
@gaurav414u
Copy link

gaurav414u commented Aug 31, 2019

Hey @shihaohong how about post-Lollipop and pre-Q devices?

@TheJulianJES
Copy link

TheJulianJES commented Aug 31, 2019

I'm thinking that just setting the navigation bar to transparent using SystemChrome.setEnabledSystemUIOverlays doesn't create the padding (for lists and more).
This already happens on iOS (with iPhone X or later), as we get a padding for the home bar there.

@shihaohong
Copy link
Contributor

shihaohong commented Aug 31, 2019

As per my original comment, please file a new issue with reproducible samples for unique, specific asks. It's hard to keep track of what needs to be done to account for full screen navigation when there are different permutations of needs by different developers.

@JavierSegoviaCordoba
Copy link

JavierSegoviaCordoba commented Sep 25, 2019

@shihaohong SystemChrome.setEnabledSystemUIOverlay this is a hack, I don't want a semi-fullscreen app...

@rydmike
Copy link

rydmike commented Sep 25, 2019

Reading all the comments here and having struggled wit this too, I think it is fairly obvious what is asked for.

A way to to make a fully transparent Android system navigation bar where only the Android navigation buttons are opaque (or semi transparent) that also plays nice with other bottom widgets used in Flutter. Meaning e.g a FAB or a bottom navigation bar should remain above the transparent navigation button area if used, but the scaffold content should paint (scroll) behind them all. It might be a good idea to have it as an option that the bottom navbars and FAB can optionally start from the "true" bottom too, then you will of course get the situation that was shown in the screenshot above, which in some special design cases might be desired or at least a needed starting point for the layout.

More discussion on the topic

Combined with the Scaffold's extendBody property and the new extendBodyBehindAppBar #39156 property, that now also extends the body behind the top system statusbar icons, we can now in Flutter easily make "fullscreen" designs that have become fairly popular, for certain apps at least.

The AppBar overlay on the top system statusbar can already be made fully or semi transparent, and now the scaffold body content can then scroll nicely behind the transparent/semitransparent (like in #39156) or even use a partial appbar, like e.g. the floating search appbar in the Android GMail app.

For a fully nice full screen look it should be possible to extend the same look and design at the bottom too behind the navigation button and nav area, as many android apps with newer designs do.

Currently it is as far as I can tell impossible to do this in Flutter on Android. It seem impossible to make the Android navigation bar transparent and have correctly colored buttons in flutter and keeping the Flutter widgets that deal with the bottom area correctly.

I have tried a solution that was based on how to modify the AndroidManifest, this got me close to the desired outcome. If I recall correctly I got a semitransparent navigation bar area, but not a fully transparent one, not on the Pixel 3XL emulator at least. Additionally Flutter's widgets got a bit confused with this approach concerning e.g. its own bottom navigation bar buttons, that then got drawn under the (semi)transparent system navigation bar and its opaque buttons, making it impossible to tap and use the Flutter bottom navigation bar buttons. I'm sure the Flutter bottom navbar could be modified or just build your own that you can move up a bit, but it becomes a bit complex to figure out on which devices it is needs to move where. It would be helpful and useful if there was a clear and easy approach for solving this built into the framework.

There is now a nice solution for the top area, but as far as I can tell the navbar area still requires some improvements to make it fully baked.


Finally, if there is some working solution I would be happy and eager to learn about it, because so far I have not found one.

@shihaohong
Copy link
Contributor

shihaohong commented Sep 26, 2019

Hi @rydmike, thank you for the detail of your ask and issues surrounding creating a transparent/translucent navigation bar. This will certainly help with figuring out what needs to be done.

I've been doing preliminary investigations into this through #40974 and unfortunately do not have a solution that achieves the desired effect (I also tried playing around with the AndroidManifest, as well as writing some Android-specific code for a Flutter project). I'm planning on exploring this further after I'm done with helping implement the Android 10 activity animation.

Edit: I might create several new issues that properly covers the different permutations of needs surrounding hiding system UI. The problem here is that it gets really tricky - these are just some of the examples of cases that need to be considered:

  1. Fullscreen/edge-to-edge that doesn't simply hide the system UI (Android Q)
  2. Fullscreen/edge-to-edge that doesn't simply hide the system UI (Android P and older)
  3. Just transparent nav bar, allows layout behind the nav bar (Android Q)
  4. Just transparent nav bar, allows layout behind the nav bar (Android P and older)

All of these cases have to do also consider how laying out widgets like the FAB and the bottom navigation bar will be affected and how to handle this in Flutter based on devices, which has been eluded to in the prior comment.

@Zazo032
Copy link
Contributor Author

Zazo032 commented Sep 26, 2019

To handle the position of some widgets, I think maybe we should modify the SafeArea widget to properly position other widgets on the screen. As Dave Burke said, this effect can be achieved by setting the navigation bar to transparent in the Android style's (theme) file, so after adding that, the next step should probably be to push the rendered layout under that navigation bar. In P and older versions, the main widget to deal with positions, as happens on iOS, should be SafeArea, which has access to the system's navigation bar insets and properly positions widgets out of that area.

@rydmike
Copy link

rydmike commented Sep 26, 2019

Thanks @shihaohong for picking up this issue again. The edits you added also make a lot of sense to me, I was planning to add similar observations and comments, but you beat me to it.

I'm sure there are more critical Flutter issues than this one, however with Android Q out, where this type of design is used almost predominantly, it has in my opinion bumped this issue up a few notches.

I experiment frequently with Windows Desktop builds and to do so I stay a lot on master branch, so whenever some solution for this lands on master, it I'd be happy to try it out.

@gaurav414u
Copy link

gaurav414u commented Sep 27, 2019

@shihaohong To give everybody the technical perspective of the android side of things (API 21+):

Capability:

view.setSystemUiVisibility( 
    // Tells the system that the window wishes the content to
    // be laid out at the most extreme scenario. 
    View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
    // Tells the system that the window wishes the content to
    // be laid out as if the navigation bar was hidden
    View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);


ViewCompat.setOnApplyWindowInsetsListener(
        floatingActionButton,
        (view, insets) -> {
              // Update view's layoutparams using insets.getSystemWindowInsetBottom/Start/End/Top()
              return insets;
        });
  • Snackbar's bottom offset is automatically taken care of by just doing this much.

v21+

  • configurable statusBarColor or windowTranslucentStatus
    • statusBarColor can’t be translucent.
    • They don’t work together. If we use windowTranslucentStatus, system applies a fixed dark scrim that can’t be changed.
  • Fully configurable navigationBarColor
    But we are limited to using dark colors as the navigation buttons remain white colored.
  • Status bar icons & navigation bar buttons always remain light.

v23+

  • windowLightStatusBar
    Enables the statusBar icons to be dark
  • statusBarColor can be translucent

v27+

  • windowLightNavigationBar
    • Enables the navigation bar buttons to be dark.
    • Means, we can use a lighter navigationBarColor and be consistent with statusBar

Flutter's current behaviour:

SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
      systemNavigationBarColor: Colors.<any>,
      statusBarColor: Colors.<any>,
      statusBarIconBrightness: Brightness.dark,
      systemNavigationBarIconBrightness: Brightness.dark,
    ));
  • [All APIs] The app is drawn behind status bar and the content can be padded using MediaQuery.of(context).padding.top when required.

  • [All APIs] App not drawn behind navigationbar.

    • Expectation:
      • How to go behind navigationBar without using android:translucentNavigation=true?
      • If drawing behind statusBar is enabled by default, ideally drawing behind navigationBar should also be enabled by default or both controlled by a flag.
      • There should be a consistent way to get the window insets for bottom, left and right. (after drawing behind navigationbar is resolved). This will help to handle the UI in landscape mode.
  • API 21-22

    • The statusBarColor or the navigationBarColor doesn't work at all.
      • statusBar remains translucent with a dark scrim, navigationBar remains black.
    • Brightness can't work as the capability is not there.
    • Expectation:
      • statusBarColor should work atleast for non-translucent colors, else fall back to dark scrim.
      • navigationBarColor should work with all the values and let the developer handle what to do on this api level.
  • API 23-26

    • The statusBarColor and statusBarIconBrightness fully work.
    • navigationBarColor doesn't work at all. It remains black.
    • systemNavigationBarIconBrightness can't work as the capability is missing.
    • Expectation:
      • navigationBarColor should work.
  • API 27+

    • All 4 work
  • Side note:
    If we use android:translucentNavigation=true in the activity [along with resizeToAvoidBottomInset: false in scaffold], the navigation bar remains translucent with a dark scrim across all the APIs and the content can be bottom padded using: MediaQuery.of(context).viewInsets.bottom.
    Even then, the snackbar's offset is not correct.

@gaodeng
Copy link

gaodeng commented May 18, 2020

any news?

Gesture Navigation: Going edge-to-edge
https://medium.com/androiddevelopers/gesture-navigation-going-edge-to-edge-812f62e4e83e
Ensure compatibility with gesture navigation
https://developer.android.com/training/gestures/gesturenav

@chachako
Copy link

chachako commented Jun 17, 2020

This work for me #40974 (comment)

@me-abhishekpal
Copy link

me-abhishekpal commented Mar 19, 2021

Can we have the transparent nav bar in 2021 ?

@github-actions
Copy link

github-actions bot commented Aug 4, 2021

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 4, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
f: material design framework platform-android
Projects
Development

No branches or pull requests