如何在 Android 活动中永久隐藏导航栏?

我想永久隐藏导航栏在我的活动(而不是整个系统 UI)。 现在我用这段代码

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

它隐藏的酒吧,但当用户触摸屏幕它再次显示。是否有办法将其永久隐藏,直到活动 onStop();

176121 次浏览

Try this:

View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);

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

Use:-

view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);

In Tablets running Android 4+, it is not possible to hide the System / Navigation Bar.

From documentation :

The SYSTEM_UI_FLAG_HIDE_NAVIGATION is a new flag that requests the navigation bar hide completely. Be aware that this works only for the navigation bar used by some handsets (it does not hide the system bar on tablets).

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

Its a security issue: https://stackoverflow.com/a/12605313/1303691

therefore its not possible to hide the Navigation on a tablet permanently with one single call at the beginning of the view creation. It will be hidden, but it will pop up when touching the Screen. So just the second touch to your screen can cause a onClickEvent on your layout. Therefore you need to intercept this call, but i haven't managed it yet, i will update my answer when i found it out. Or do you now the answer already?

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.

I think the blow code will help you, and add those code before setContentView()

getWindow().setFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

Add those code behind setContentView() getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);

It's my solution:

First, define boolean that indicate if navigation bar is visible or not.

boolean navigationBarVisibility = true //because it's visible when activity is created

Second create method that hide navigation bar.

private void setNavigationBarVisibility(boolean visibility){
if(visibility){
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
navigationBarVisibility = false;
}


else
navigationBarVisibility = true;
}

By default, if you click to activity after hide navigation bar, navigation bar will be visible. So we got it's state if it visible we will hide it.

Now set OnClickListener to your view. I use a surfaceview so for me:

    playerSurface.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setNavigationBarVisibility(navigationBarVisibility);
}
});

Also, we must call this method when activity is launched. Because we want hide it at the beginning.

        setNavigationBarVisibility(navigationBarVisibility);

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.

I think this code will resolve your issue. Copy and paste this code on your MainActivity.java

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


View decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener
(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {


if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
hideNavigationBar();
}
}
});
}






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

It will works on Android-10. I hope it will helps.

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)
}
}

You can hide Navigator Bar using this:

    @Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
View decorView = getWindow().getDecorView();
if(hasFocus){
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|
View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
);
}
}

This way you can hide Navigation Buttons without hiding Status bar

Try this for all android version including Android 30(R).

For more check this class: https://github.com/fiftyonemoon/Rapid/blob/main/rapid/src/main/java/com/fom/rapid/app/UI.java

Show/Hide all system bars:

 public void hideSystemUI(Window window) { //pass getWindow();


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {


window.getInsetsController().hide(WindowInsets.Type.systemBars());


} else {


View decorView = window.getDecorView();


int uiVisibility = decorView.getSystemUiVisibility();


uiVisibility |= View.SYSTEM_UI_FLAG_LOW_PROFILE;
uiVisibility |= View.SYSTEM_UI_FLAG_FULLSCREEN;
uiVisibility |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
uiVisibility |= View.SYSTEM_UI_FLAG_IMMERSIVE;
uiVisibility |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
}


decorView.setSystemUiVisibility(uiVisibility);
}
}




public void showSystemUI(Window window) { //pass getWindow();


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {


window.getInsetsController().show(WindowInsets.Type.systemBars());


} else {
View decorView = window.getDecorView();


int uiVisibility = decorView.getSystemUiVisibility();


uiVisibility &= ~View.SYSTEM_UI_FLAG_LOW_PROFILE;
uiVisibility &= ~View.SYSTEM_UI_FLAG_FULLSCREEN;
uiVisibility &= ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
uiVisibility &= ~View.SYSTEM_UI_FLAG_IMMERSIVE;
uiVisibility &= ~View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
}


decorView.setSystemUiVisibility(uiVisibility);
}
}

Here is the hide and show system UI for android 11 and Below. But below from Android its deprecated.

private fun hideSystemUI() {
WindowCompat.setDecorFitsSystemWindows(window, false)
WindowInsetsControllerCompat(window, drawerLayoutID).let { controller ->
controller.hide(WindowInsetsCompat.Type.systemBars())
controller.systemBarsBehavior =
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
}
}
    

private fun showSystemUI() {
WindowCompat.setDecorFitsSystemWindows(window, true)
WindowInsetsControllerCompat(
window,
drawerLayoutID
).show(WindowInsetsCompat.Type.systemBars())
}
    

private fun hideSystemUIBeloR() {
val decorView: View = window.decorView
val uiOptions = decorView.systemUiVisibility
var newUiOptions = uiOptions
newUiOptions = newUiOptions or View.SYSTEM_UI_FLAG_LOW_PROFILE
newUiOptions = newUiOptions or View.SYSTEM_UI_FLAG_FULLSCREEN
newUiOptions = newUiOptions or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
newUiOptions = newUiOptions or View.SYSTEM_UI_FLAG_IMMERSIVE
newUiOptions = newUiOptions or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
decorView.systemUiVisibility = newUiOptions
}
    

private fun showSystemUIBelowR() {
val decorView: View = window.decorView
val uiOptions = decorView.systemUiVisibility
var newUiOptions = uiOptions
newUiOptions = newUiOptions and View.SYSTEM_UI_FLAG_LOW_PROFILE.inv()
newUiOptions = newUiOptions and View.SYSTEM_UI_FLAG_FULLSCREEN.inv()
newUiOptions = newUiOptions and View.SYSTEM_UI_FLAG_HIDE_NAVIGATION.inv()
newUiOptions = newUiOptions and View.SYSTEM_UI_FLAG_IMMERSIVE.inv()
newUiOptions = newUiOptions and View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY.inv()
decorView.systemUiVisibility = newUiOptions
}