How to hide navigation bar permanently in android activity?

159,863

Solution 1

Snippets:

FullScreenFragment.java

HideNavigationBarComponent.java


This is for Android 4.4+

Try out immersive mode https://developer.android.com/training/system-ui/immersive.html

Fast snippet (for an Activity class):

private int currentApiVersion;

@Override
@SuppressLint("NewApi")
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);

    currentApiVersion = android.os.Build.VERSION.SDK_INT;

    final int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
        | View.SYSTEM_UI_FLAG_FULLSCREEN
        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;

    // This work only for android 4.4+
    if(currentApiVersion >= Build.VERSION_CODES.KITKAT)
    {

        getWindow().getDecorView().setSystemUiVisibility(flags);

        // Code below is to handle presses of Volume up or Volume down.
        // Without this, after pressing volume buttons, the navigation bar will
        // show up and won't hide
        final View decorView = getWindow().getDecorView();
        decorView
            .setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener()
            {

                @Override
                public void onSystemUiVisibilityChange(int visibility)
                {
                    if((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0)
                    {
                        decorView.setSystemUiVisibility(flags);
                    }
                }
            });
    }

}


@SuppressLint("NewApi")
@Override
public void onWindowFocusChanged(boolean hasFocus)
{
    super.onWindowFocusChanged(hasFocus);
    if(currentApiVersion >= Build.VERSION_CODES.KITKAT && hasFocus)
    {
        getWindow().getDecorView().setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_FULLSCREEN
                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
    }
}

If you have problems when you press Volume up or Volume down that your navigation bar show. I added code in onCreate see setOnSystemUiVisibilityChangeListener

Here is another related question:

Immersive mode navigation becomes sticky after volume press or minimise-restore

Solution 2

Do this.

public void FullScreencall() {
    if(Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api
        View v = this.getWindow().getDecorView();
        v.setSystemUiVisibility(View.GONE);
    } else if(Build.VERSION.SDK_INT >= 19) {
        //for new api versions.
        View decorView = getWindow().getDecorView();
        int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
        decorView.setSystemUiVisibility(uiOptions);
    }
}

This works 100% and you can do same for lower API versions, even if it's a late answer I hope it will helps someone else.

If you want this to be permanent, just call FullScreencall() inside your onResume() method.

Solution 3

For people looking at a simpler solution, I think you can just have this one line of code in onStart()

  getWindow().getDecorView().setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|
            View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);

It's called Immersive mode. You may look at the official documentation for other possibilities.

Solution 4

According to Android Developer site

I think you cant(as far as i know) hide navigation bar permanently..

However you can do one trick. Its a trick mind you.

Just when the navigation bar shows up when user touches the screen. Immediately hide it again. Its fun.

Check this.

void setNavVisibility(boolean visible) {
int newVis = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
        | SYSTEM_UI_FLAG_LAYOUT_STABLE;
if (!visible) {
    newVis |= SYSTEM_UI_FLAG_LOW_PROFILE | SYSTEM_UI_FLAG_FULLSCREEN
            | SYSTEM_UI_FLAG_HIDE_NAVIGATION;
}

// If we are now visible, schedule a timer for us to go invisible.
if (visible) {
    Handler h = getHandler();
    if (h != null) {
        h.removeCallbacks(mNavHider);
        if (!mMenusOpen && !mPaused) {
            // If the menus are open or play is paused, we will not auto-hide.
            h.postDelayed(mNavHider, 1500);
        }
    }
}

// Set the new desired visibility.
setSystemUiVisibility(newVis);
mTitleView.setVisibility(visible ? VISIBLE : INVISIBLE);
mPlayButton.setVisibility(visible ? VISIBLE : INVISIBLE);
mSeekView.setVisibility(visible ? VISIBLE : INVISIBLE);
}

See this for more information on this ..

Hide System Bar in Tablets

Solution 5

The other answers mostly use the flags for setSystemUiVisibility() method in View. However, this API is deprecated since Android 11. Check my article about modifying the system UI visibility for more information. The article also explains how to handle the cutouts properly or how to listen to the visibility changes.

Here are code snippets for showing / hiding system bars with the new API as well as the deprecated one for backward compatibility:

/**
 * Hides the system bars and makes the Activity "fullscreen". If this should be the default
 * state it should be called from [Activity.onWindowFocusChanged] if hasFocus is true.
 * It is also recommended to take care of cutout areas. The default behavior is that the app shows
 * in the cutout area in portrait mode if not in fullscreen mode. This can cause "jumping" if the
 * user swipes a system bar to show it. It is recommended to set [WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER],
 * call [showBelowCutout] from [Activity.onCreate]
 * (see [Android Developers article about cutouts](https://developer.android.com/guide/topics/display-cutout#never_render_content_in_the_display_cutout_area)).
 * @see showSystemUI
 * @see addSystemUIVisibilityListener
 */
fun Activity.hideSystemUI() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        window.insetsController?.let {
            // Default behavior is that if navigation bar is hidden, the system will "steal" touches
            // and show it again upon user's touch. We just want the user to be able to show the
            // navigation bar by swipe, touches are handled by custom code -> change system bar behavior.
            // Alternative to deprecated SYSTEM_UI_FLAG_IMMERSIVE.
            it.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
            // make navigation bar translucent (alternative to deprecated
            // WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
            // - do this already in hideSystemUI() so that the bar
            // is translucent if user swipes it up
            window.navigationBarColor = getColor(R.color.internal_black_semitransparent_light)
            // Finally, hide the system bars, alternative to View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
            // and SYSTEM_UI_FLAG_FULLSCREEN.
            it.hide(WindowInsets.Type.systemBars())
        }
    } else {
        // Enables regular immersive mode.
        // For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE.
        // Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY
        @Suppress("DEPRECATION")
        window.decorView.systemUiVisibility = (
                // Do not let system steal touches for showing the navigation bar
                View.SYSTEM_UI_FLAG_IMMERSIVE
                        // Hide the nav bar and status bar
                        or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                        or View.SYSTEM_UI_FLAG_FULLSCREEN
                        // Keep the app content behind the bars even if user swipes them up
                        or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
        // make navbar translucent - do this already in hideSystemUI() so that the bar
        // is translucent if user swipes it up
        @Suppress("DEPRECATION")
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
    }
}

/**
 * Shows the system bars and returns back from fullscreen.
 * @see hideSystemUI
 * @see addSystemUIVisibilityListener
 */
fun Activity.showSystemUI() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        // show app content in fullscreen, i. e. behind the bars when they are shown (alternative to
        // deprecated View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION and View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
        window.setDecorFitsSystemWindows(false)
        // finally, show the system bars
        window.insetsController?.show(WindowInsets.Type.systemBars())
    } else {
        // Shows the system bars by removing all the flags
        // except for the ones that make the content appear under the system bars.
        @Suppress("DEPRECATION")
        window.decorView.systemUiVisibility = (
                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
    }
}
Share:
159,863
Sujith S Manjavana
Author by

Sujith S Manjavana

I got a lot of help from StackOverflow. Just trying to payback.. :-)

Updated on August 13, 2021

Comments

  • Sujith S Manjavana
    Sujith S Manjavana over 2 years

    I want to hide navigation bar permanently in my activity(not whole system ui). now i'm using this piece of code

    getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
    

    It hides the bar but when user touches the screen it showing again. is there any way to hide it permanently until activity onStop();

  • Sujith S Manjavana
    Sujith S Manjavana about 10 years
    NO it's give me same result
  • Finder
    Finder over 9 years
    When user swipes top/ bottom of the screen,that will display the Semi-transparent navigation bars temporarily appear and then hide again. IS IT POSSIBLE TO HIDE THAT TOO ?
  • Muhammed Refaat
    Muhammed Refaat over 9 years
    @KarthickRamu I found a way, just look at my answer down :)
  • Finder
    Finder over 9 years
    @MuhammedRefaat Your hint needs a rooted device :(
  • Muhammed Refaat
    Muhammed Refaat over 9 years
    yeah, sry about that :(
  • Shajeel Afzal
    Shajeel Afzal over 8 years
    I get this exception: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.android.internal.widget.ActionBarContainer.setAlpha(floa‌​t)' on a null object reference at com.android.internal.app.WindowDecorActionBar.doHide(WindowD‌​ecorActionBar.java:8‌​22)
  • Shajeel Afzal
    Shajeel Afzal over 8 years
    Thanks for the gist, will the navigation bar hide permanently? And i think i need to put all my activity logic in the fragment and show it in the activity?
  • zackygaurav
    zackygaurav almost 7 years
    Field requires API level 21+
  • Abandoned Cart
    Abandoned Cart about 6 years
    I recommend taking a look at developer.android.com/training/system-ui/immersive.html, which explains that your method simply hides the bar until there is interaction and again shortly after interaction is complete.
  • Jack
    Jack over 5 years
    @DawidDrozd Thank you, but I have a problem, My activity root layout is RelativeLayout, and it has a child view that is set android:layout_alignParentBottom="true", the navigation bar disappear but the child view doesn't move to bottom edge of the screen, as if the navigation bar is set to invisible not gone, could you help?
  • Gelldur
    Gelldur over 5 years
    @Jack Probably you need remeasure whole view but not sure. Try to invalidate like here: stackoverflow.com/questions/6946478/…
  • Joe Lapp
    Joe Lapp almost 5 years
    If you want to make use of the space that the navigation bar occupied, you have to remove all occurrences of android:fitsSystemWindows="true" from your views. Android Studio includes this attribute when generating some layouts. See stackoverflow.com/a/42501330/650894
  • Leszek
    Leszek over 3 years
    Hmm, that works, with one caveat: when in my app I press any button that causes a new window to appear on the screen ( 'window' - i.e. a DialogFrament, a PopupWindow, or simply a Spinner's selecttion list window) - then the navigation bar re-appears and stays there until the window in question gets dismissed. Any cure for that?
  • Angel Koh
    Angel Koh over 3 years
    I tried your codes with the BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE flag on the emulator, but the navigation bar will pop up and remain displayed when i touch the screen. Any idea what else i should set to get the STICKY functionality on Android 11?
  • Miloš Černilovský
    Miloš Černilovský over 3 years
    @AngelKoh You have to call hideSystemUI() manually if you want to hide it. Check the article mentioned in my answer, it contains all these details. Sticky mode means the bars will be transparent if the user swipes them up and the app will receive the touch events as well (see developer.android.com/training/system-ui/…).
  • Angel Koh
    Angel Koh over 3 years
    yes hideSystemUI() is called and the Ui got hidden the first time. however when i touch the screen afterwards, the navigation bar pops back out and stays displayed.
  • Miloš Černilovský
    Miloš Černilovský over 3 years
    The purpose of BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE is to prevent the system stealing touches and displaying the bars. So I am not sure what could cause this without seeing / debugging the real app.
  • Admin
    Admin over 3 years
    I am getting err ( cannot find symbol View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);) ``` @Override protected void onStart() { getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_HIDE_NAVIGATION| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); super.onStart(); }```
  • Mimouni
    Mimouni over 3 years
    That works but I used only oncreate(){... } part. I didn't integrate the function onWindowFocusChanged and all is working perfectly.
  • Francis
    Francis almost 3 years
    @AngelKoh did you found the solution? As you mentioned BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE react to click, not just swipe
  • Kishan Solanki
    Kishan Solanki over 2 years
    It doesn't hide navigation bar (andriod 10 home gesture navigations)
  • Abubakar
    Abubakar about 2 years
    Thanks Bro For Your help