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

Android API 35+下Java实现状态栏/导航栏颜色与高度的问题求助

Android API 35+ 状态栏/导航栏适配实现代码

以下是针对API 35+优化的Java工具类,包含系统栏背景色设置、高度获取及刘海区域参数获取逻辑,适配最新API废弃规则:

import android.app.Activity;
import android.graphics.Color;
import android.graphics.Rect;
import android.os.Build;
import android.view.DisplayCutout;
import android.view.View;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowInsetsController;

import java.util.List;

public class AndroidSystemBarUtils {

    // 设置状态栏与导航栏背景色,自动适配文字图标深浅
    public static void setSystemBarsColor(Activity activity, int statusBarColor, int navBarColor) {
        Window window = activity.getWindow();
        // 让布局延伸至系统栏下方,确保背景色生效
        window.setDecorFitsSystemWindows(false);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            WindowInsetsController insetsController = window.getInsetsController();
            if (insetsController == null) return;

            window.setStatusBarColor(statusBarColor);
            window.setNavigationBarColor(navBarColor);

            // 根据背景色自动切换状态栏文字图标深浅
            boolean isStatusBarDark = isColorDark(statusBarColor);
            insetsController.setSystemBarsAppearance(
                    isStatusBarDark ? WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS : 0,
                    WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
            );

            // 根据背景色自动切换导航栏图标深浅
            boolean isNavBarDark = isColorDark(navBarColor);
            insetsController.setSystemBarsAppearance(
                    isNavBarDark ? WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS : 0,
                    WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
            );
        }
    }

    // 获取状态栏高度(需在View附着窗口后调用)
    public static int getStatusBarHeight(Activity activity) {
        int height = 0;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            WindowInsets insets = activity.getWindow().getDecorView().getRootWindowInsets();
            if (insets != null) {
                height = insets.getInsets(WindowInsets.Type.statusBars()).top;
            }
        } else {
            // 兼容旧版本,可按需保留
            int resId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
            if (resId > 0) height = activity.getResources().getDimensionPixelSize(resId);
        }
        return height;
    }

    // 获取导航栏高度(需在View附着窗口后调用)
    public static int getNavigationBarHeight(Activity activity) {
        int height = 0;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            WindowInsets insets = activity.getWindow().getDecorView().getRootWindowInsets();
            if (insets != null) {
                height = insets.getInsets(WindowInsets.Type.navigationBars()).bottom;
            }
        } else {
            // 兼容旧版本,可按需保留
            int resId = activity.getResources().getIdentifier("navigation_bar_height", "dimen", "android");
            if (resId > 0) height = activity.getResources().getDimensionPixelSize(resId);
        }
        return height;
    }

    // 获取刘海区域所有裁剪矩形
    public static List<Rect> getDisplayCutoutAreas(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            WindowInsets insets = activity.getWindow().getDecorView().getRootWindowInsets();
            if (insets != null) {
                DisplayCutout cutout = insets.getDisplayCutout();
                if (cutout != null) return cutout.getBoundingRects();
            }
        }
        return null;
    }

    // 获取刘海顶部安全边距(状态栏额外高度)
    public static int getDisplayCutoutTopInset(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            WindowInsets insets = activity.getWindow().getDecorView().getRootWindowInsets();
            if (insets != null) {
                DisplayCutout cutout = insets.getDisplayCutout();
                if (cutout != null) return cutout.getSafeInsetTop();
            }
        }
        return 0;
    }

    // 判断颜色是否为深色,用于切换系统栏文字图标颜色
    private static boolean isColorDark(int color) {
        double darkness = 1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255;
        return darkness >= 0.5;
    }
}

核心注意事项

  • 调用高度、刘海参数方法时,必须确保View已附着到窗口(比如在Activity的onWindowFocusChanged(boolean hasFocus)中调用,或给View添加OnAttachStateChangeListener监听),否则WindowInsets会返回null,导致高度为0。
  • 必须执行window.setDecorFitsSystemWindows(false),否则布局无法延伸至系统栏,Insets获取会异常。
  • QT开发者可将此类打包为Android库,或直接在QT对应的Android入口类中实现,通过JNI调用对应方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 08:02:46