You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android 7+应用中彻底禁用状态栏与导航栏的实现方案问询

彻底禁用Android 7+状态栏和导航栏的方案

哥们,我太懂你这种烦恼了!之前用主题或者FLAG_FULLSCREEN确实只能临时隐藏系统栏,一滑就出来,根本达不到“彻底禁用”的效果。要实现真正的全屏锁定,得用上Android的沉浸式全屏模式,还要针对不同版本做适配,下面给你分版本讲具体实现:

一、Android 7.0 - Android 10(API 24~29)

这几个版本还在用setSystemUiVisibilityAPI,核心是把几个系统UI标志组合起来,并且在窗口获取焦点时重新设置(避免系统操作导致栏重新显示)。

1. 先配置Activity主题

AndroidManifest.xml里给目标Activity设置全屏主题,确保基础的全屏属性生效:

<activity
    android:name=".YourFullscreenActivity"
    android:theme="@style/Theme.AppCompat.Light.NoActionBar.Fullscreen">
</activity>

对应的主题样式(在res/values/styles.xml里):

<style name="Theme.AppCompat.Light.NoActionBar.Fullscreen" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowContentOverlay">@null</item>
</style>

2. 在Activity中设置沉浸式标志

重写onWindowFocusChanged方法,每次窗口获取焦点时强制隐藏系统栏并锁定:

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    if (hasFocus) {
        View decorView = getWindow().getDecorView();
        decorView.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);
    }
}

注意:如果用SYSTEM_UI_FLAG_IMMERSIVE_STICKY,滑动后栏会临时显示然后自动隐藏;而SYSTEM_UI_FLAG_IMMERSIVE需要手动点击栏上的“返回”按钮才会隐藏,如果你要彻底不让滑动唤起,就用IMMERSIVE,并且确保每次焦点变化都重新设置。

3. 处理屏幕旋转等配置变化

如果你的Activity允许屏幕旋转,记得在onConfigurationChanged里重新设置系统UI:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // 重新应用全屏设置
    View decorView = getWindow().getDecorView();
    decorView.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);
}

别忘了在AndroidManifest.xml的Activity里加上配置变化声明:

<activity
    android:name=".YourFullscreenActivity"
    android:theme="@style/Theme.AppCompat.Light.NoActionBar.Fullscreen"
    android:configChanges="orientation|screenSize|keyboardHidden">
</activity>

二、Android 11+(API 30及以上)

从API30开始,setSystemUiVisibility被废弃了,官方推荐用WindowInsetsController来控制系统栏,更灵活。

1. 配置主题(和之前一致)

还是先给Activity设置全屏主题,确保基础属性正确。

2. 使用WindowInsetsController控制全屏

在Activity的onCreate或者onWindowFocusChanged里设置:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_fullscreen);
    
    // 隐藏状态栏和导航栏
    WindowInsetsController insetsController = getWindow().getInsetsController();
    if (insetsController != null) {
        // 隐藏状态栏和导航栏
        insetsController.hide(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
        // 设置行为:禁止通过滑动唤起系统栏,仅允许双击顶部显示
        insetsController.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_TAP);
    }
    
    // 可选:保持屏幕常亮,避免锁屏后系统栏重新显示
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}

3. 焦点变化的保险措施

和旧版本一样,在onWindowFocusChanged里重新隐藏系统栏,防止某些系统操作(比如弹出通知后)导致栏显示:

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    if (hasFocus) {
        WindowInsetsController insetsController = getWindow().getInsetsController();
        if (insetsController != null) {
            insetsController.hide(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
        }
    }
}

三、额外注意事项

  • 虚拟导航栏 vs 物理按键:如果设备是物理导航键,那没办法禁用,但虚拟导航栏可以通过上面的方法彻底隐藏。
  • 系统权限:不需要额外权限,这些操作都是Activity级别的设置,只要你的应用是前台运行就生效。
  • 厂商定制系统:部分厂商(如小米、华为)会定制系统UI,建议在目标设备上测试,上述方案是通用的基础实现。

内容的提问来源于stack exchange,提问作者DarkVss

火山引擎 最新活动