基础配置
AndroidManifest.xml配置
<!-- 支持全面屏显示 -->
<meta-data
android:name="android.max_aspect"
android:value="2.4" />
<!-- 适配异形屏 -->
<meta-data
android:name="android.notch_support"
android:value="true" />
启用全屏模式
// 在Activity的onCreate中设置
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);
}
沉浸式状态栏适配
状态栏透明化
// 设置状态栏透明
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.TRANSPARENT);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
// 设置导航栏透明(可选)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.setNavigationBarColor(Color.TRANSPARENT);
}
内容延伸到状态栏
<!-- values-v21/styles.xml -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowTranslucentStatus">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
刘海屏/挖孔屏适配
获取安全区域
public class DisplayUtils {
// 获取刘海屏安全区域
public static Rect getSafeInsetRect(Window window) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
DisplayCutout cutout = window.getDecorView().getRootWindowInsets().getDisplayCutout();
if (cutout != null) {
return new Rect(
cutout.getSafeInsetLeft(),
cutout.getSafeInsetTop(),
cutout.getSafeInsetRight(),
cutout.getSafeInsetBottom()
);
}
}
return new Rect(0, 0, 0, 0);
}
// 获取状态栏高度
public static int getStatusBarHeight(Context context) {
int resourceId = context.getResources()
.getIdentifier("status_bar_height", "dimen", "android");
return resourceId > 0 ?
context.getResources().getDimensionPixelSize(resourceId) : 0;
}
}
动态调整布局
public class FullScreenHelper {
public static void adjustForFullScreen(View view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
view.setOnApplyWindowInsetsListener((v, insets) -> {
DisplayCutout cutout = insets.getDisplayCutout();
if (cutout != null) {
int safeInsetTop = cutout.getSafeInsetTop();
int safeInsetBottom = cutout.getSafeInsetBottom();
// 设置padding避免内容被遮挡
v.setPadding(
v.getPaddingLeft(),
Math.max(v.getPaddingTop(), safeInsetTop),
v.getPaddingRight(),
Math.max(v.getPaddingBottom(), safeInsetBottom)
);
}
return insets;
});
}
}
}
布局适配方案
ConstraintLayout适配方案
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<!-- 状态栏占位View -->
<View
android:id="@+id/status_bar_placeholder"
android:layout_width="0dp"
android:layout_height="@dimen/status_bar_height"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<!-- 主要内容区域 -->
<androidx.core.widget.NestedScrollView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/status_bar_placeholder"
app:layout_constraintBottom_toTopOf="@id/nav_bar_placeholder"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<!-- 内容 -->
</androidx.core.widget.NestedScrollView>
<!-- 导航栏占位View -->
<View
android:id="@+id/nav_bar_placeholder"
android:layout_width="0dp"
android:layout_height="@dimen/nav_bar_height"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
边距适配方案
<!-- values/dimens.xml --> <dimen name="status_bar_height">24dp</dimen> <dimen name="nav_bar_height">48dp</dimen> <!-- values-v21/dimens.xml --> <dimen name="status_bar_height">@android:dimen/status_bar_height</dimen> <!-- values-xxhdpi/dimens.xml (针对高屏占比设备) --> <dimen name="status_bar_height">28dp</dimen>
厂商特定适配
华为刘海屏适配
public class HuaweiNotchUtils {
public static boolean hasNotch(Context context) {
try {
ClassLoader cl = context.getClassLoader();
Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");
Method get = HwNotchSizeUtil.getMethod("hasNotchInScreen");
return (boolean) get.invoke(HwNotchSizeUtil);
} catch (Exception e) {
return false;
}
}
public static void setFullScreenWindow(Activity activity) {
try {
WindowManager.LayoutParams layoutParams = activity.getWindow().getAttributes();
Class layoutParamsExCls = Class.forName("com.huawei.android.view.LayoutParamsEx");
Constructor con = layoutParamsExCls.getConstructor(WindowManager.LayoutParams.class);
Object layoutParamsExObj = con.newInstance(layoutParams);
Method method = layoutParamsExCls.getMethod("addHwFlags", int.class);
method.invoke(layoutParamsExObj, 0x00010000); // FLAG_NOTCH_SUPPORT
} catch (Exception e) {
e.printStackTrace();
}
}
}
小米刘海屏适配
public class XiaomiNotchUtils {
public static boolean hasNotch(Context context) {
try {
return "1".equals(SystemProperties.get("ro.miui.notch"));
} catch (Exception e) {
return false;
}
}
public static int getNotchHeight(Context context) {
int resourceId = context.getResources()
.getIdentifier("notch_height", "dimen", "android");
return resourceId > 0 ?
context.getResources().getDimensionPixelSize(resourceId) : 0;
}
}
手势导航适配
全屏手势处理
public class GestureNavigationHelper {
public static void handleGestureNavigation(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// 启用全屏手势
activity.getWindow().getAttributes().systemUiVisibility |=
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
// 监听导航栏显示/隐藏
View decorView = activity.getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener(visibility -> {
boolean isNavigationHidden = (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0;
adjustBottomPadding(activity, isNavigationHidden);
});
}
}
private static void adjustBottomPadding(Activity activity, boolean navigationHidden) {
View rootView = activity.findViewById(android.R.id.content);
if (rootView != null) {
int bottomPadding = navigationHidden ? 0 : getNavigationBarHeight(activity);
rootView.setPadding(
rootView.getPaddingLeft(),
rootView.getPaddingTop(),
rootView.getPaddingRight(),
bottomPadding
);
}
}
}
测试建议
测试设备覆盖
- 带刘海的设备(iPhone X样式)
- 挖孔屏设备
- 弹出式摄像头设备
- 屏下摄像头设备
- 曲面屏设备
测试场景
// 编写测试用例
@Test
public void testFullScreenLayout() {
// 测试横竖屏切换
// 测试手势导航
// 测试异形屏区域点击
// 测试安全区域显示
}
总结建议
- 优先使用Android官方API(API Level 28+)
- 渐进增强:为旧版本提供fallback方案
- 动态适配:运行时检测设备特性
- 用户可选:提供设置选项让用户选择显示模式
- 充分测试:覆盖主流厂商的不同全面屏方案
这样的适配方案能够确保OpenClaw在各种全面屏设备上都有良好的显示效果和用户体验。

版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。