How to hide navigation bar permanently in android activity?
Solution 1
Snippets:
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 ..
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)
}
}
Sujith S Manjavana
I got a lot of help from StackOverflow. Just trying to payback.. :-)
Updated on August 13, 2021Comments
-
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 about 10 yearsNO it's give me same result
-
Finder over 9 yearsWhen 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 over 9 years@KarthickRamu I found a way, just look at my answer down :)
-
Finder over 9 years@MuhammedRefaat Your hint needs a rooted device :(
-
Muhammed Refaat over 9 yearsyeah, sry about that :(
-
Shajeel Afzal over 8 yearsI get this exception:
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.android.internal.widget.ActionBarContainer.setAlpha(float)' on a null object reference at com.android.internal.app.WindowDecorActionBar.doHide(WindowDecorActionBar.java:822)
-
Shajeel Afzal over 8 yearsThanks 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 almost 7 yearsField requires API level 21+
-
Abandoned Cart about 6 yearsI 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 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 over 5 years@Jack Probably you need remeasure whole view but not sure. Try to invalidate like here: stackoverflow.com/questions/6946478/…
-
Joe Lapp almost 5 yearsIf 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 over 3 yearsHmm, 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 over 3 yearsI 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ý 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 over 3 yearsyes 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ý over 3 yearsThe 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 over 3 yearsI 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 over 3 yearsThat works but I used only oncreate(){... } part. I didn't integrate the function onWindowFocusChanged and all is working perfectly.
-
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 over 2 yearsIt doesn't hide navigation bar (andriod 10 home gesture navigations)
-
Abubakar about 2 yearsThanks Bro For Your help