First editing pass

This commit is contained in:
Corbin Crutchley
2020-04-15 22:24:10 -07:00
parent 2997973fcf
commit 42dfb2f454

View File

@@ -1,7 +1,7 @@
--- ---
{ {
title: "Draw under the Android NavBar Using React Native", title: "Draw under the Android NavBar Using React Native",
description: "Android allows you to draw content under the navigation bar. It's a very cool effect and Google themselves suggest it for all new apps! Let's add that to our React Native apps", description: "Android allows you to draw content under the navigation bar. It's a very cool effect, and Google themselves suggest it for all new apps! Let's add that to our React Native apps",
published: '2020-04-16T05:12:03.284Z', published: '2020-04-16T05:12:03.284Z',
authors: ['crutchcorn'], authors: ['crutchcorn'],
tags: ['android', 'react native'], tags: ['android', 'react native'],
@@ -17,7 +17,7 @@ While working on [my React Native mobile app]([https://g](https://github.com/cru
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. 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.
Feel free to follow along with the code samples, but if you're looking for looking for the easiest solution, [you might want to read to the bottom to see how to easily integrate it into your app without all of the manual work](#react-native-immersive-bars). Feel free to follow along with the code samples, but if you're looking for the easiest solution, [you might want to read to the bottom to see how to easily integrate it into your app without all of the manual work](#react-native-immersive-bars).
# The Wrong Way {#flag-layout-no-limits} # The Wrong Way {#flag-layout-no-limits}
@@ -25,7 +25,7 @@ After doing some initial research, I found myself presented with various StackOv
> Window flag: allow window to extend outside of the screen. > 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 all of the project initially to make the configuration: 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:
``` ```
android > app > src > main > java > yourpackagepath > MainActivity.java android > app > src > main > java > yourpackagepath > MainActivity.java
@@ -53,11 +53,11 @@ protected void onCreate(Bundle savedInstanceState) {
Once this was done, I loaded my app and "et voilà"! Once this was done, I loaded my app and "et voilà"!
![The FAB is placed under the navbar as expected](./flag_layout_no_limits.png)= ![The FAB is placed under the navbar as expected](./flag_layout_no_limits.png)
"Success", I'd thought to myself. Clearly, since the FAB was now being drawn under the navbar, that was indication that the goal had been reached. However, I faced difficulties when trying to use [the `safe-area-context` package](https://github.com/th3rdwave/react-native-safe-area-context) in order to draw margins and padding to move the FAB above the navbar once again. "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](https://github.com/th3rdwave/react-native-safe-area-context) to draw margins and paddings (to move the FAB above the navbar), I faced difficulties.
When I utilized the following code: When I utilized the following code:
@@ -136,11 +136,11 @@ Oddly enough, not only did this not solve the problem, but it made the bottom ba
![The bottom bar from before but now a solid color](./fits_system_translucent.png) ![The bottom bar from before but now a solid color](./fits_system_translucent.png)
Drats! From the start we go again. Drats! We'll have to start all over again.
# The Right Way # The Right Way
After re-reading some of the resources I was looking at, I realized the answer was in [the initial GitHub issue I was first looking into when `FLAG_LAYOUT_NO_LIMIT` didn't work](https://github.com/th3rdwave/react-native-safe-area-context/issues/8). It suggested to use [a View flag called `SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION`](https://developer.android.com/reference/android/view/View#SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION). After reading the documentation for the flag, I knew it was a step in the right direction: After re-reading some of the resources I was looking at, I realized the answer was in [the initial GitHub issue I was first looking into when `FLAG_LAYOUT_NO_LIMIT` didn't work](https://github.com/th3rdwave/react-native-safe-area-context/issues/8). It suggested using [a View flag called `SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION`](https://developer.android.com/reference/android/view/View#SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION). After reading the documentation for the flag, I knew it was a step in the right direction:
> View would like its window to be laid out as if it has requested `SYSTEM_UI_FLAG_HIDE_NAVIGATION`, even if it currently hasn't. > View would like its window to be laid out as if it has requested `SYSTEM_UI_FLAG_HIDE_NAVIGATION`, even if it currently hasn't.
@@ -173,7 +173,7 @@ protected void onCreate(Bundle savedInstanceState) {
![The bottom bar is now fully transparent](./transparent.png) ![The bottom bar is now fully transparent](./transparent.png)
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 is exactly what we were hoping for! 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: > If your bottom bar is still a solid color like the one here:
> ![The bottom bar in solid white](./fits_system_transparent.png) > ![The bottom bar in solid white](./fits_system_transparent.png)
@@ -182,7 +182,7 @@ That's done it! Not only is the button being drawn under the navbar fully transp
# Other API Versions {#api-versions} # Other API Versions {#api-versions}
While the code I've mentioned thus far works, it only realistically 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](https://developer.android.com/reference/android/view/View#SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR). To edgecase this, we'll need to add some conditional logic to draw our own dark translucent bar for versions lower than this: 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](https://developer.android.com/reference/android/view/View#SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR). 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 ```java
if ( Build.VERSION.SDK_INT <= Build.VERSION_CODES.O) { if ( Build.VERSION.SDK_INT <= Build.VERSION_CODES.O) {
@@ -192,7 +192,7 @@ if ( Build.VERSION.SDK_INT <= Build.VERSION_CODES.O) {
} }
``` ```
Likewise, [the support for dark statusbar icons has only been present since API Level 23 (Android M)](https://developer.android.com/reference/android/view/WindowManager.LayoutParams#SYSTEM_UI_FLAG_LIGHT_STATUS_BAR). This too, will need to be edgecased: Likewise, [the support for dark status bar icons has only been present since API Level 23 (Android M)](https://developer.android.com/reference/android/view/WindowManager.LayoutParams#SYSTEM_UI_FLAG_LIGHT_STATUS_BAR). This too will need to be edge-cased:
```java ```java
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
@@ -202,12 +202,12 @@ if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
} }
``` ```
When viewing the app on older versions of Android (like M), you'll the respective bars as a semi-transparent bar: When viewing the app on older versions of Android (like M), you'll see the respective bars as a semi-transparent bar:
![The statusbar is transparent while the navbar is translucent](./transparent_m.png) ![The statusbar is transparent while the navbar is translucent](./transparent_m.png)
# The Easy Method {#react-native-immersive-bars} # The Easy Method {#react-native-immersive-bars}
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! 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](https://gitshark.dev) and created a package for you to utilize! Fear not, fellow developer! I've taken my learnings from implementing this into [my mobile Git Client](https://gitshark.dev) and created a package for you to utilize!
@@ -237,7 +237,7 @@ video: title: "A working dark switch with transparent navbar": ./android_10.mp4
# Conclusion # 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](/unicorns/fennifith) and [Sasi Kanth](https://github.com/msasikanth) 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. 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](/unicorns/fennifith) and [Sasi Kanth](https://github.com/msasikanth) 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. 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.