The idea of drawing under the navbar intrigued me. After lots of research, I was finally able to implement it in my app, but not without struggles. Let's walk through how to do it manually and what I ended up doing to solve the issue myself.
After doing some initial research, I found myself presented with various StackOverflows and official documentation pointing towards a Window flag FLAG_LAYOUT_NO_LIMITS to, quote:
Window flag: allow window to extend outside of the screen.
This seemed perfect to me! Being able to draw content outside the edges of the screen would surely allow me to draw under the navbar, right? I looked for the MainActivity.java file that loads the project initially to make the configuration:
Once this was done, I loaded my app and "et voilĂ "!
"Success," I'd thought to myself. Since the FAB was drawn under the navbar, I thought the goal had been achieved! However, once I tried the safe-area-context package to draw margins and paddings (to move the FAB above the navbar), I faced difficulties.
After even further research, I'd found myself with a potential alternative: Translucent bars! I knew that the ability to draw under navbars was often accompanied with translucent bars in previous versions of Android! If we revert changes to the MainActivity.java file back to how they were initially, and simply update our styles.xml file located at:
android > app > src > main > res > values > styles.xml
And added the translucent flags, maybe that would work:
After making the changes and restarting my app, I was greeted with the following:
Fantastic! It's not only drawing under the navbar, but it's also registering the correct inset.bottom height we wanted to display in the titlebar! That said, I was still hoping for a fully transparent navbar. I knew it was possible. Maybe if I added explicit code to make the navbar transparent, that would work:
When using other layout flags, we would like a stable view of the content insets given to fitSystemWindows
While this might be a bit confusing, it's essentially saying that not only would it draw under the navbar, but it would do so consistently, allowing us to draw under the navbar, just like we wanted!
For good measure, let's add in explicitly transparent navbars and status bar codes:
That's done it! Not only is the button being drawn under the navbar fully transparently, but the number at the top of the screen indicates that the Inset API is registering the height of the navbar still! This behavior is exactly what we were hoping for!
If your bottom bar is still a solid color like the one here:
Then you've forgotten to remove the fitsSystemWindows flag that we added in our styles.xml flag previously. Once that (and the windowDrawsSystemBarBackgrounds flag) was removed, it worked for me
Other API Versions
While the code I've mentioned thus far works, it only really works well on Android O (API Level 26) and above. That's only about 60% of Android devices out there! Why does this only work well on Android O? Well, if you have a light background, it only makes sense to have dark buttons in the navigation bar. That functionality has only existed since Android introduced the SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR Vew flag in API 26. To edge-case this, we'll need to add some conditional logic to draw our own dark translucent bar for versions lower than this:
java
if ( Build.VERSION.SDK_INT<=Build.VERSION_CODES.O) {
When viewing the app on older versions of Android (like M), you'll see the respective bars as a semi-transparent bar:
The Easy Method
Let's not sugar coat it: It's tedious to make changes to native Android code in order to support all of the various API levels there are, the various forms of OEM issues that could arise. Likewise, if your app implements a dark mode, there's now another level of challenge: You have to toggle the light and dark navigation buttons yourself!
Fear not, fellow developer! I've taken my learnings from implementing this into my mobile Git Client and created a package for you to utilize!
It supports dark mode switching, as many API levels as React Native does, and much more!
Conclusion
This feature was not a trivial one for me to implement. Not often is it that such a short article reflects how long I'd spent debugging and researching this issue. I want to make sure to thank James Fenn and Sasi Kanth for helping me debug and research for this. I'm happy I did so, though. I think it adds a nice level of polish to my app, and I think you'll find the same in your app as well. Hopefully, the package I made is able to ease the process for you. If you have any comments or questions regarding the package, please refer to the GitHub issues for said project.
Otherwise, if you have comments or questions about the article, you can leave them in the comments down below. We also have a newsletter that you can subscribe to for more articles like this: I plan on writing much more about React Native as I develop my app.