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

时间:2014-02-12 09:56:46

标签: android fullscreen navigationbar

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

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

它会隐藏栏,但当用户触摸屏幕时,它会再次显示。有没有办法永久隐藏它,直到活动onStop();

13 个答案:

答案 0 :(得分:90)

<强>片断:

FullScreenFragment.java

HideNavigationBarComponent.java


适用于Android 4.4 +

尝试身临其境模式https://developer.android.com/training/system-ui/immersive.html

快速摘要(适用于活动类):

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

如果按导航栏显示的音量调高或音量调低时遇到问题。我在onCreate中添加了代码,请参阅setOnSystemUiVisibilityChangeListener

这是另一个相关问题:

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

答案 1 :(得分:39)

这样做。

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

这可以100%工作,你可以为较低的API版本做同样的事情,即使这是一个迟到的答案,我希望它能帮助其他人。

如果您希望这是永久性的,只需在FullscreenCall()方法中调用onResume()

答案 2 :(得分:3)

根据Android Developer site

我认为你不能(据我所知)永久隐藏导航栏。

但是你可以做一个技巧。这是一个让你着迷的技巧。

当用户触摸屏幕时显示navigation bar。马上再次隐藏它。 很有趣。

检查

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

有关此内容的更多信息,请参阅此内容。

Hide System Bar in Tablets

答案 3 :(得分:3)

使用: -

view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);

在运行Android 4+的平板电脑中,无法隐藏系统/导航栏。

来自documentation

  

SYSTEM_UI_FLAG_HIDE_NAVIGATION是一个请求的新标志   导航栏完全隐藏。请注意,这仅适用于   某些手机​​使用的导航栏(它不会隐藏系统栏   在平板电脑上。)

答案 4 :(得分:1)

这是一个安全问题: https://stackoverflow.com/a/12605313/1303691

因此,无法在视图创建开始时通过一次调用永久隐藏平板电脑上的导航。它将被隐藏,但触摸屏幕时会弹出。因此,只需对屏幕进行第二次触摸即可在布局上生成onClickEvent。因此你需要拦截这个电话,但我还没有管理它,当我发现它时我会更新我的答案。或者你现在已经回答了吗?

答案 5 :(得分:1)

我认为打击代码可以帮助您,并在setContentView()

之前添加这些代码
getWindow().setFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

在setContentView()后面添加这些代码   。getWindow()getDecorView()setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);

答案 6 :(得分:1)

其他答案大多使用setSystemUiVisibility()View方法的标志。但是,从Android 11开始不推荐使用该API。Check my article about modifying the system UI visibility for more information.本文还介绍了如何正确处理剪切点或如何监听可见性更改。

以下是使用新的API显示/隐藏系统栏的代码段,以及为了向后兼容而弃用的代码段:

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

答案 7 :(得分:0)

试试这个。

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

如果有帮助,请告诉我......:)

答案 8 :(得分:0)

这是我的解决方案:

首先,定义指示导航栏是否可见的布尔值。

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

隐藏导航栏的第二个创建方法。

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

默认情况下,如果在隐藏导航栏后单击活动,则会显示导航栏。所以我们得到它的状态,如果它可见我们将隐藏它。

现在将OnClickListener设置为您的视图。我对我使用了surfaceview:

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

此外,我们必须在启动活动时调用此方法。因为我们想在开头隐藏它。

        setNavigationBarVisibility(navigationBarVisibility);

答案 9 :(得分:0)

对于正在寻找更简单解决方案的人们,我认为您只需在其中包含这一行代码 onStart()

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

这称为沉浸模式。您可以查看官方文档以了解其他可能性。

答案 10 :(得分:0)

我认为这段代码可以解决您的问题。将此代码复制并粘贴到MainActivity.java


function getCookie(cname) {
  var name = cname + "=";
  var decodedCookie = decodeURIComponent(document.cookie);
  var ca = decodedCookie.split(';');
  for(var i = 0; i <ca.length; i++) {
    var c = ca[i];
    while (c.charAt(0) == ' ') {
      c = c.substring(1);
    }
    if (c.indexOf(name) == 0) {
      return c.substring(name.length, c.length);
    }
  }
  return "";
}

function setCookie(cname, cvalue) {
  document.cookie = cname + "=" + cvalue + ";";
}

function start(id){
 if (getCookie('id') === '' ) {
     setCookie('id', JSON.stringify([+id]));
    }
 else {
    let ids = JSON.parse(getCookie('id'))
    console.log(ids)
    ids.push(+id); 
    setCookie('id', JSON.stringify(ids));
  } 
}

function sendID(id) {
  console.log(document.getElementById("user-id").value)
  start(id);
  alert(getCookie("id"))
}

它将在Android-10上运行。我希望这会有所帮助。

答案 11 :(得分:0)

您可以使用以下方法隐藏导航栏:

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

这样你就可以隐藏导航按钮而不隐藏状态栏

答案 12 :(得分:0)

在包括 Android 30(R) 在内的所有 android 版本上试试这个。

更多检查这个类:https://github.com/fiftyonemoon/Rapid/blob/main/rapid/src/main/java/com/fom/rapid/app/UI.java

显示/隐藏所有系统栏:

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