如何实现Java Android应用永久全屏?防止滑动唤起状态栏与导航栏
彻底阻止全屏模式下滑弹出状态栏/导航栏的解决方案
你的代码用了SYSTEM_UI_FLAG_IMMERSIVE_STICKY,这个模式的特性是用户滑动后状态栏/导航栏会临时显示,几秒后自动隐藏,但没法彻底阻止弹出。要实现近似“彻底阻止”的效果,得调整UI标记并添加监听回调,同时适配不同Android版本的API。
核心修改思路
- 把
IMMERSIVE_STICKY换成IMMERSIVE(非粘性沉浸模式)——这个模式下用户滑动会显示状态栏/导航栏,但不会自动隐藏,需要我们主动重新隐藏 - 添加系统UI可见性变化监听,一旦检测到状态栏/导航栏显示,立刻重新设置为隐藏状态
- 在
onResume里重新应用全屏设置,避免应用从后台返回后系统恢复状态栏/导航栏 - 针对Android 11(API 30)及以上版本,用
WindowInsetsController新API实现更可靠的控制
完整代码实现
兼容旧版本(API < 30)
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_main); View decorView = getWindow().getDecorView(); // 移除IMMERSIVE_STICKY,改用IMMERSIVE int uiOptions = 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; decorView.setSystemUiVisibility(uiOptions); // 监听系统UI变化,一旦显示就重新隐藏 decorView.setOnSystemUiVisibilityChangeListener(visibility -> { if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) { decorView.setSystemUiVisibility(uiOptions); } }); } @Override protected void onResume() { super.onResume(); // 后台返回后重新应用全屏设置 View decorView = getWindow().getDecorView(); int uiOptions = 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; decorView.setSystemUiVisibility(uiOptions); }
适配Android 11及以上(API >= 30)
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_main); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { WindowInsetsController insetsController = getWindow().getInsetsController(); if (insetsController != null) { // 隐藏状态栏和导航栏 insetsController.hide(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars()); // 监听窗口内边距变化,一旦状态栏/导航栏弹出就立即隐藏 getWindow().getDecorView().setOnApplyWindowInsetsListener((v, insets) -> { insetsController.hide(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars()); return insets.consume(); }); } } else { // 旧版本逻辑,同上面的代码 View decorView = getWindow().getDecorView(); int uiOptions = 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; decorView.setSystemUiVisibility(uiOptions); decorView.setOnSystemUiVisibilityChangeListener(visibility -> { if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) { decorView.setSystemUiVisibility(uiOptions); } }); } } @Override protected void onResume() { super.onResume(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { WindowInsetsController insetsController = getWindow().getInsetsController(); if (insetsController != null) { insetsController.hide(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars()); } } else { View decorView = getWindow().getDecorView(); int uiOptions = 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; decorView.setSystemUiVisibility(uiOptions); } }
注意事项
- Android系统没有提供完全禁止用户滑动显示状态栏/导航栏的API,因为这涉及系统级交互权限。上述方案是通过“立即重新隐藏”的方式,达到近似彻底阻止的效果
- 必须在
onResume中重新设置,否则应用从后台返回后,系统可能自动恢复状态栏/导航栏的显示 - 不同Android版本的API差异大,做好版本适配能提升兼容性
内容的提问来源于stack exchange,提问作者avcismail
相关产品推荐
相关产品推荐

