You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在系统栏间绘制内容并保持系统栏完全不透明?

解决方案:让应用接收全屏幕AMotionEvent并适配两种窗口模式

一、非全屏窗口模式:状态栏/导航栏可见且不拦截触摸事件

要实现状态栏、应用窗口、导航栏依次显示,同时让应用接收屏幕所有像素的触摸事件,核心是让应用窗口布局延伸至系统栏下方,同时禁用系统栏的触摸拦截:

  1. 在Activity的onCreate方法中配置窗口属性:
Window window = getWindow();
// 让窗口布局覆盖整个屏幕(包括系统栏区域)
window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

// 设置状态栏、导航栏为半透明(保持可见,避免遮挡应用内容)
window.setStatusBarColor(Color.parseColor("#80000000"));
window.setNavigationBarColor(Color.parseColor("#80000000"));

// 配置系统UI可见性,确保应用布局延伸至系统栏区域
View decorView = window.getDecorView();
decorView.setSystemUiVisibility(
        View.SYSTEM_UI_FLAG_LAYOUT_STABLE
        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
);
  1. 布局文件中设置根布局属性:
    确保根布局的android:fitsSystemWindows="false",避免系统自动调整布局避开系统栏区域。

这样设置后,状态栏和导航栏会显示在应用内容上方,但所有屏幕区域的AMotionEvent都会优先传递给应用,不会被系统栏拦截。

二、全屏窗口模式:应用占满屏幕,边缘拉动唤起系统栏

针对全屏需求,使用沉浸式粘性全屏模式替代普通窗口标记,既实现应用全屏显示,又支持边缘拉动唤起系统栏,同时保证应用接收全屏幕触摸事件:

  1. 基础全屏配置(兼容Android 10及以下):
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
        // 粘性沉浸式模式:边缘拉动临时显示系统栏,松手后自动隐藏
        View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
        // 隐藏状态栏和导航栏
        | View.SYSTEM_UI_FLAG_FULLSCREEN
        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
        // 让布局延伸至系统栏区域
        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
);

// 让窗口覆盖全屏幕
getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

// 设置系统栏透明,视觉上完全全屏
getWindow().setStatusBarColor(Color.TRANSPARENT);
getWindow().setNavigationBarColor(Color.TRANSPARENT);
  1. Android 11+适配:
    使用WindowInsetsController替代旧的系统UI可见性配置,兼容性更好:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    WindowInsetsController insetsController = getWindow().getInsetsController();
    if (insetsController != null) {
        // 隐藏状态栏和导航栏
        insetsController.hide(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
        // 设置系统栏行为:边缘滑动临时显示
        insetsController.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
    }
}

同样需确保根布局android:fitsSystemWindows="false",保证触摸事件能覆盖全屏幕。

关键说明

  • 两种模式都通过让应用窗口覆盖全屏幕实现触摸事件的全接收,系统栏仅作为上层绘制元素,不会拦截非系统交互的触摸事件。
  • 若需处理系统栏显示/隐藏的回调,可重写onSystemUiVisibilityChange(Android 10及以下)或监听WindowInsets变化(Android 11+)。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 10:25:19