我如何使一个活动全屏?没有通知栏。


当前回答

从mozilla找到解决方案,他们在这里做了一个扩展库

如果链接中断,这里是代码


/**
 * Retrieves a {@link WindowInsetsControllerCompat} for the top-level window decor view.
 */
fun Window.getWindowInsetsController(): WindowInsetsControllerCompat {
    return WindowInsetsControllerCompat(this, this.decorView)
}


/**
 * Attempts to call immersive mode using the View to hide the status bar and navigation buttons.
 * @param onWindowFocusChangeListener optional callback to ensure immersive mode is stable
 * Note that the callback reference should be kept by the caller and be used for [exitImmersiveModeIfNeeded] call.
 */
fun Activity.enterToImmersiveMode(
    onWindowFocusChangeListener: ViewTreeObserver.OnWindowFocusChangeListener? = null
) {
    window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
    window.getWindowInsetsController().apply {
        hide(WindowInsetsCompat.Type.systemBars())
        systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
    }

    // We need to make sure system bars do not become permanently visible after interactions with content
    // see https://github.com/mozilla-mobile/fenix/issues/20240
    onWindowFocusChangeListener?.let {
        window.decorView.viewTreeObserver?.addOnWindowFocusChangeListener(it)
    }
}

/**
 * Attempts to come out from immersive mode using the View.
 * @param onWindowFocusChangeListener optional callback to ensure immersive mode is stable
 * Note that the callback reference should be kept by the caller and be the same used for [enterToImmersiveMode] call.
 */
@Suppress("DEPRECATION")
fun Activity.exitImmersiveModeIfNeeded(
    onWindowFocusChangeListener: ViewTreeObserver.OnWindowFocusChangeListener? = null
) {
    if (WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON and window.attributes.flags == 0) {
        // We left immersive mode already.
        return
    }
    onWindowFocusChangeListener?.let {
        window.decorView.viewTreeObserver?.removeOnWindowFocusChangeListener(it)
    }
    window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
    window.getWindowInsetsController().apply {
        show(WindowInsetsCompat.Type.systemBars())
    }
}

其他回答

科特林

遵循谷歌文档,有一个简单的方法:

override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
if (hasFocus) hideSystemUI() }


private fun hideSystemUI() {
// 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
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE
        // Set the content to appear under the system bars so that the
        // content doesn't resize when the system bars hide and show.
        or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
        or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
        or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        // Hide the nav bar and status bar
        or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
        or View.SYSTEM_UI_FLAG_FULLSCREEN)      }


// Shows the system bars by removing all the flags
// except for the ones that make the content appear under the system bars.
private fun showSystemUI() {
window.decorView.systemUiVisibility = 
(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
        or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
        or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)       }

谷歌文档

getWindow().addFlags(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

根据安卓开发者培训

你应该做到以下几点:

科特林:

private fun hideSystemBars() {
  val windowInsetsController =
      ViewCompat.getWindowInsetsController(window.decorView) ?: return
  // Configure the behavior of the hidden system bars
  windowInsetsController.systemBarsBehavior =
      WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
  // Hide both the status bar and the navigation bar
  windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
}

Java:

private void hideSystemBars() {
  WindowInsetsControllerCompat windowInsetsController =
      ViewCompat.getWindowInsetsController(getWindow().getDecorView());
  if (windowInsetsController == null) {
    return;
  }
  // Configure the behavior of the hidden system bars
  windowInsetsController.setSystemBarsBehavior(
      WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
  );
  // Hide both the status bar and the navigation bar
  windowInsetsController.hide(WindowInsetsCompat.Type.systemBars());
}

在onCreate()中的setContentView之后使用这个方法,并通过getWindow()传递Window对象。

    public void makeActivityFullScreen(Window window){
    View decorView = window.getDecorView();
    //        int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
       window.getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
    }
    decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
            | View.SYSTEM_UI_FLAG_FULLSCREEN
            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
    );
}

此代码也将适用于缺口屏幕。要检查缺口全屏,你需要安卓P,但如果你有一个缺口显示手机,然后去设置->显示设置->应用程序显示比例->选择你的应用程序->有两个安全的选项是显示和全屏,请选择全屏并运行应用程序,你可以看到缺口的全屏也没有安卓派

在Android 10上,没有一款适合我。

但我工作得很好(oncreate的第一行):

    View decorView = getWindow().getDecorView();
    int uiOptions = View.SYSTEM_UI_FLAG_IMMERSIVE;
    decorView.setSystemUiVisibility(uiOptions);

    setContentView(....);

    if (getSupportActionBar() != null) {
        getSupportActionBar().hide();
    }

享受:)