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

如何获取顶部带Notch的屏幕尺寸?适配Android P及更早版本设备

我来给你梳理下具体的解决方案,分两种场景(Android P及以上、Pre-P设备)来处理,毕竟Android P之前官方没有统一的刘海适配标准,得兼容各家厂商的自定义实现:

解决方案:分Android P及以上、Pre-P设备适配

一、Android P(API 28+):官方标准适配

Android 9.0开始官方引入了DisplayCutout类来统一处理刘海/挖孔屏,你可以通过以下步骤适配:

  1. 获取安全区域(Safe Area)尺寸
    别再直接用getRealSize拿全屏幕尺寸了,应该获取排除刘海区域的安全区域,这样游戏内容就不会跑到刘海里或者超出屏幕:

    // 可以在Activity的onWindowFocusChanged或者View的onAttachedToWindow中调用
    View decorView = getWindow().getDecorView();
    decorView.setOnApplyWindowInsetsListener((v, insets) -> {
        DisplayCutout cutout = insets.getDisplayCutout();
        if (cutout != null) {
            // 获取刘海四周的安全边距:top/left/right/bottom
            int safeInsetTop = cutout.getSafeInsetTop();
            int safeInsetBottom = cutout.getSafeInsetBottom();
            int safeInsetLeft = cutout.getSafeInsetLeft();
            int safeInsetRight = cutout.getSafeInsetRight();
            
            // 计算安全区域的实际可用尺寸
            int safeWidth = screenSize.x - safeInsetLeft - safeInsetRight;
            int safeHeight = screenSize.y - safeInsetTop - safeInsetBottom;
            
            // 用safeWidth和safeHeight设置游戏视图的渲染区域,或者调整内容布局
        }
        return insets.consumeSystemWindowInsets();
    });
    
  2. 设置窗口刘海模式
    在AndroidManifest.xml中给游戏Activity添加主题属性,控制内容是否允许延伸到刘海区域:

    <activity android:name=".YourGameActivity">
        <meta-data
            android:name="android.window.layoutInDisplayCutoutMode"
            android:value="never" /> <!-- 可选值:default/shortEdges/never -->
    </activity>
    
    • never:内容完全避开刘海区域,安全区域就是排除刘海的可用区域
    • shortEdges:允许内容延伸到刘海所在的短边(比如竖屏时的顶部刘海)
    • default:系统默认行为,通常允许内容延伸到刘海区域

二、Pre-P设备(Android 8/8.1等):厂商自定义适配

Android 9之前没有官方刘海API,需要针对主流厂商(华为、小米、OPPO、vivo)分别处理,核心是通过反射或厂商提供的API获取刘海尺寸,再手动调整游戏内容的显示区域:

华为设备(比如你的P20)

华为提供了自定义的刘海检测和尺寸获取方法,用反射就能实现:

// 判断设备是否有刘海
public static boolean hasNotchInScreen(Context context) {
    boolean hasNotch = false;
    try {
        ClassLoader cl = context.getClassLoader();
        Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");
        Method method = HwNotchSizeUtil.getMethod("hasNotchInScreen");
        hasNotch = (boolean) method.invoke(HwNotchSizeUtil);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return hasNotch;
}

// 获取刘海尺寸(返回int数组,[0]是宽度,[1]是高度)
public static int[] getNotchSize(Context context) {
    int[] notchSize = new int[2];
    try {
        ClassLoader cl = context.getClassLoader();
        Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");
        Method method = HwNotchSizeUtil.getMethod("getNotchSize");
        notchSize = (int[]) method.invoke(HwNotchSizeUtil);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return notchSize;
}

拿到刘海高度后,给游戏视图顶部留出对应高度的padding,或者直接把游戏的渲染区域从刘海下方开始计算。

小米设备

小米的刘海适配可以通过自定义WindowManager参数和反射实现:

// 判断是否有刘海
public static boolean hasNotch(Context context) {
    boolean hasNotch = false;
    try {
        ClassLoader cl = context.getClassLoader();
        Class MiuiFeature = cl.loadClass("android.os.SystemProperties");
        Method get = MiuiFeature.getMethod("getInt", String.class, int.class);
        hasNotch = (int) get.invoke(MiuiFeature, "ro.miui.notch", 0) == 1;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return hasNotch;
}

// 设置窗口允许延伸到刘海区域(可选)
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
getWindow().setAttributes(lp);

OPPO设备

OPPO的刘海适配可以用系统特性检测和反射:

// 判断是否有刘海
public static boolean hasNotch(Context context) {
    return context.getPackageManager().hasSystemFeature("com.oppo.feature.screen.heteromorphism");
}

// 获取刘海尺寸
public static int[] getNotchSize(Context context) {
    int[] notchSize = new int[2];
    try {
        ClassLoader cl = context.getClassLoader();
        Class OppoDisplay = cl.loadClass("com.oppo.util.OppoDisplayCutout");
        Method method = OppoDisplay.getMethod("getRealNotchSize");
        notchSize = (int[]) method.invoke(OppoDisplay);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return notchSize;
}

通用优化建议

  • 不管用哪种方案,都不要直接依赖getRealSize返回的全屏幕尺寸,始终基于安全区域来布局游戏内容,这是避免内容超出屏幕或被刘海遮挡的核心。
  • 对于全屏游戏,建议给游戏视图添加对应刘海高度的顶部padding,或者将游戏的渲染区域直接限制在安全区域内,保证所有核心内容都能正常显示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:43:47