全屏沉浸模式适配
在 AndroidManifest.xml 中配置:

<application
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<!-- 允许内容延伸到刘海区域 -->
<meta-data
android:name="android.notch_support"
android:value="true" />
</application>
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:windowSoftInputMode="adjustResize"
android:screenOrientation="landscape"
android:resizeableActivity="true"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
</activity>
代码层面适配
在 MainActivity.java 中添加:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 刘海屏适配
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
WindowManager.LayoutParams params = getWindow().getAttributes();
params.layoutInDisplayCutoutMode =
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
getWindow().setAttributes(params);
}
// 隐藏状态栏和导航栏
hideSystemUI();
}
private void hideSystemUI() {
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
decorView.setSystemUiVisibility(uiOptions);
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
hideSystemUI();
}
}
布局文件适配
在 res/values/dimens.xml 中添加:
<resources>
<!-- 刘海屏安全区域边距 -->
<dimen name="notch_padding">30dp</dimen>
<dimen name="status_bar_height">24dp</dimen>
</resources>
修改布局文件,避免内容被刘海遮挡:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:paddingTop="@dimen/status_bar_height">
<!-- 游戏画面区域 -->
<SurfaceView
android:id="@+id/surfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- 虚拟按键区域 -->
<RelativeLayout
android:id="@+id/controls_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:paddingBottom="@dimen/notch_padding">
<!-- 虚拟按键布局 -->
</RelativeLayout>
</RelativeLayout>
动态获取刘海信息
private void adjustForNotch() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
DisplayCutout displayCutout = getWindow().getDecorView()
.getRootWindowInsets().getDisplayCutout();
if (displayCutout != null) {
// 获取刘海区域信息
List<Rect> boundingRects = displayCutout.getBoundingRects();
int safeInsetTop = displayCutout.getSafeInsetTop();
int safeInsetBottom = displayCutout.getSafeInsetBottom();
int safeInsetLeft = displayCutout.getSafeInsetLeft();
int safeInsetRight = displayCutout.getSafeInsetRight();
// 根据刘海信息调整布局
View controlsLayout = findViewById(R.id.controls_layout);
if (controlsLayout != null) {
controlsLayout.setPadding(
safeInsetLeft,
0,
safeInsetRight,
safeInsetBottom
);
}
}
}
}
针对不同厂商的特殊处理
public class NotchUtils {
public static boolean hasNotch(Context context) {
boolean hasNotch = false;
try {
// 华为
if (Build.MANUFACTURER.equalsIgnoreCase("HUAWEI")) {
Class<?> clz = Class.forName("com.huawei.android.util.HwNotchSizeUtil");
Method get = clz.getMethod("hasNotchInScreen");
hasNotch = (boolean) get.invoke(clz);
}
// 小米
else if (Build.MANUFACTURER.equalsIgnoreCase("XIAOMI")) {
hasNotch = getSystemPropertiesInt("ro.miui.notch", 0) == 1;
}
// OPPO
else if (Build.MANUFACTURER.equalsIgnoreCase("OPPO")) {
hasNotch = context.getPackageManager()
.hasSystemFeature("com.oppo.feature.screen.heteromorphism");
}
// VIVO
else if (Build.MANUFACTURER.equalsIgnoreCase("VIVO")) {
hasNotch = getSystemPropertiesInt("ro.vivo.notch.support", 0) == 1;
}
} catch (Exception e) {
e.printStackTrace();
}
return hasNotch;
}
private static int getSystemPropertiesInt(String key, int def) {
try {
Class<?> c = Class.forName("android.os.SystemProperties");
Method get = c.getMethod("getInt", String.class, int.class);
return (int) get.invoke(c, key, def);
} catch (Exception e) {
return def;
}
}
}
游戏画面渲染适配
在 OpenGL 渲染时,考虑刘海区域:
// 在 GLSurfaceView.Renderer 中
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
// 考虑刘海区域的实际可用尺寸
int usableWidth = width;
int usableHeight = height;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
DisplayCutout cutout = getWindow().getDecorView()
.getRootWindowInsets().getDisplayCutout();
if (cutout != null) {
usableHeight = height - cutout.getSafeInsetTop() - cutout.getSafeInsetBottom();
}
}
GLES20.glViewport(0, 0, usableWidth, usableHeight);
// 设置投影矩阵等
}
注意事项:
- 测试多种刘海屏设备:不同厂商的刘海实现方式不同
- 横竖屏适配:OpenClaw 通常横屏使用,需考虑横向刘海
- 兼容性:保持对非刘海屏设备的兼容
- 用户设置:可添加设置项允许用户关闭刘海适配
- 性能:避免频繁获取刘海信息,应在布局变化时获取
这些适配措施能确保 OpenClaw 在刘海屏设备上正常显示,游戏控件不会被刘海遮挡,提供更好的游戏体验。
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。