29

How can I hide the Android Navigation Bar in React Native?

I'm referring to the bar at the bottom of the screen that has the software back button and home button, not the component at the top of the page that comes with the Navigator Component.

Android Navigation Bar

This page on android.com explains how to do it for native developers. Can someone explain how to accomplish this via React Native apps? Thanks.

Axeva
  • 4,697
  • 6
  • 40
  • 64

9 Answers9

34

If you're looking to achieve this permanently you'll have to hide the Navbar when the app is created and when it comes back into focus.

To do so, add this in your MainActivity.java:

...
import android.os.Bundle;
import android.view.View;

public class MainActivity extends ReactActivity {

    ...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        hideNavigationBar();
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            hideNavigationBar();
        }
    }

    private void hideNavigationBar() {
        getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
    }
}

You may want to make it "immersive" so that the user can still access the navigation bar by pulling from the bottom of the screen. To do so, add the View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY flag:

...
import android.os.Bundle;
import android.view.View;

public class MainActivity extends ReactActivity {

    ...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        hideNavigationBar();
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            hideNavigationBar();
        }
    }

    private void hideNavigationBar() {
        getWindow().getDecorView().setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);

    }
}

You can find more options on the android documentation.

Louis Zawadzki
  • 463
  • 5
  • 6
  • I had didn't know how to apply the code in my project, your answer is very helpful. Thanks!! – brouk.develop Feb 10 '20 at 03:39
  • What if I want to change it dynamically? – shoopi Oct 08 '20 at 22:00
  • This answer does work, you just have to add all those methods into the file MainActivity.java located inside "android/app/src/main/java/[...]/MainApplication.java" – Gabriel Dec 27 '21 at 02:30
  • I'm unable to see the navbar in the simulator, so I'm just going off a client's Pixel 4. I updated the MainActivity.java as above but they said they're still seeing the bar. Could the above code be deprecated at all? – JCraine Feb 21 '22 at 05:02
  • When I do this, if I click in the app, it instantly loses full-screen-ness. How can I avoid that? – Elliptica Apr 03 '23 at 21:18
9

To hide the Android Navigation bar you can do that using react-native-navigation-bar-color it allows you to show or hide the navigation bar. You can see more in the documentation here. Note that it will not work on Expo as it requires you to link native code.

Installation is fairly straight forward:

npm install react-native-navigation-bar-color --save

Then you need to link the package (only for react-native <= 0.59.0):

react-native link react-native-navigation-bar-color

Once you have done that you can use it in the following way:

import {
  HideNavigationBar,
  ShowNavigationBar,
} from 'react-native-navigation-bar-color';

Then when you want to show the navigation bar you just use

ShowNavigationBar();

And to hide it you can use:

HideNavigationBar();
GabLeRoux
  • 16,715
  • 16
  • 63
  • 81
Andrew
  • 26,706
  • 9
  • 85
  • 101
6

Building off of Martin Konicek's answer:

I went ahead and wrote the Package and Module you need here: https://gist.github.com/dhrrgn/16a8dfa7581a682627c6

You need to add it in your MainActivity.java file in the getPackages method, and send the package the ReactActivity object like this: new NavigationBarAndroidPackage(this)

Note: The code is untested, but it should work for you (you need to change the package on the first line). I just used the example code provided in the link you sent as an example. Modify to your needs.

Dan Horrigan
  • 1,275
  • 7
  • 8
  • This is awesome! Just one thing: can it be done without storing the Activity in a field? The Activity will be destroyed on screen rotation or when the app goes into background, and we're leaking the old instance and can't access the new one. There's a way to get the Context in the module just when it's needed though, check out the base class for the module. – Martin Konicek Mar 17 '16 at 03:03
  • The `getWindow()` command is only available on the `Activity`, and as far as I know there is no way to access the `ReactActivity` object through the `ReactApplicationContext`. I am fairly new to the Android world, so my knowledge of the Activity lifecycle is limited. What is the correct approach here? If `ReactApplicationContext` had a method like `getReactApplicationActivity()`, that would solve the issue. We actually need the `ReactActivity` in several of our modules in our app, so any help here would be appreciated. – Dan Horrigan Mar 17 '16 at 03:13
  • I think a lot of apps would benefit from a canonical way of accessing the `ReactActivity` object, as it is needed to get access to the `Application`, `Window`, etc. (sorry for the double comment...stupid length restrictions :P) – Dan Horrigan Mar 17 '16 at 03:17
  • This is fantastic, thanks for the fast turn around. @MartinKonicek it sounds like you have some concerns about memory usage. Is there an alternate approach you would suggest? – Axeva Mar 17 '16 at 03:36
  • Turns out there's also a method getCurrentActivity, make sure to read the Javadoc: https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContextBaseJavaModule.java It is used in the DialogModule for example. – Martin Konicek Mar 17 '16 at 18:38
  • Ah, not sure how I missed that Martin. Thanks for pointing that out. I updated the Gist accordingly. – Dan Horrigan Mar 20 '16 at 02:10
  • Finally getting back to this. The approach above will hide the Nav Bar temporarily, but as soon as you interact with the screen (to scroll, for example), it returns. I've tried variations on this theme, but the results are always the same. Alas, it seems like it's not as easy as I had hoped. – Axeva Apr 19 '16 at 19:37
  • I managed to add the native module correctly, but when I call `hide` I get this error: `Only the original thread that created a view hierarchy can touch its views` – Alejandro Corredor Apr 25 '18 at 23:01
  • For anyone having this issue in 2018, I had to use `com.facebook.react.bridge.UiThreadUtil` for running the hiding inside `runOnUiThread` – Alejandro Corredor Apr 25 '18 at 23:34
4

I've created a package with navigation bar hide/show, color change and more.

react-native-system-navigation-bar

Install

yarn add react-native-system-navigation-bar

or

npm install react-native-system-navigation-bar

Links

https://www.npmjs.com/package/react-native-system-navigation-bar

https://github.com/kadiraydinli/react-native-system-navigation-bar

kadiraydinli
  • 176
  • 6
1

Use this: https://github.com/Anthonyzou/react-native-full-screen

usage:

import FullScreen from 'react-native-full-screen'
FullScreen.onFullScreen()
FullScreen.offFullScreen()
Croolsby
  • 1,416
  • 1
  • 14
  • 14
1

for expo builds:

  expo install expo-navigation-bar

prevents content from jumping up with the navbar

  NavigationBar.setPositionAsync("absolute");

hides the navbar

  NavigationBar.setVisibilityAsync("hidden");   

transparent background

  NavigationBar.setBackgroundColorAsync("#ffffff00");

user can still swipe to show buttons

  NavigationBar.setBehaviorAsync("inset-swipe");

I tried to wrap my screen in <TouchableWithoutFeedback > to be able to use onPress prop with NavigationBar.setVisibilityAsync("hidden"), but even without onPress the bottom navbar shows only for a brief second on swipe

besthost
  • 759
  • 9
  • 14
0

There is no built-in API to do this from JavaScript.

The good news is in React Native you can expose any native functionality to JavaScript, by writing a native module. See documentation.

This way you can provide a JS function like NavigationBarAndroid.hide() and make it call the API you linked to.

Martin Konicek
  • 39,126
  • 20
  • 90
  • 98
  • Great suggestion Martin, thanks. Unfortunately I'm an iOS guy and not an Android guy. If this were and iOS issue I could jump in and do that easily enough. Since it's Android I will really have to invest some hefty effort. That's why I was hoping it was a problem that's already been solved. Maybe it will come to me brushing up on Java again, but I'm crossing my fingers that someone might have a simpler suggestion. – Axeva Mar 17 '16 at 02:07
0

Im in Android 9 and i did test the

import {HideNavigationBar} from 'react-native-navigation-bar-color';

but when Make Alt tabbing to another app, and returns then the nav bar appears again.

The best solution for me until moment is as said

Louis Zawadzki

Copying that on my mainactivity.java works fine, and always hide after changes.

0

I was stuck at the exact same point today. I found a medium article that got the job done. This question seems to be quite old however, some new readers might find this helpful.

https://medium.com/@mykl.ashton/how-to-hide-the-android-pie-navigation-bar-in-react-native-895e34c9e41

In this article, the writer has written native java methods to control the navigation bar and then used react native bridge to access the methods from react side.

It's a long article but has worked fantastically for me! hope this helps!

Suraj Ingle
  • 372
  • 4
  • 18