核心概念
安全区域(Safe Area)
- iOS: 需要适配 iPhone X 及以后机型
- Android: 适配各种异形屏(刘海、水滴、挖孔等)
- Web: 处理浏览器全屏时的安全区域
iOS 适配方案
Info.plist 配置
<key>UIViewControllerBasedStatusBarAppearance</key> <true/> <key>UIStatusBarStyle</key> <string>UIStatusBarStyleLightContent</string>
SwiftUI 适配
import SwiftUI
struct ContentView: View {
var body: some View {
Text("Hello, OpenClaw!")
.edgesIgnoringSafeArea(.all) // 忽略安全区域
.padding(.top, UIApplication.shared.windows.first?.safeAreaInsets.top ?? 0)
}
}
UIKit 适配
if #available(iOS 11.0, *) {
// 使用 safeAreaLayoutGuide
NSLayoutConstraint.activate([
view.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
view.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
])
}
Android 适配方案
AndroidManifest.xml 配置
<meta-data
android:name="android.notch_support"
android:value="true" />
全屏模式适配
// 使用 WindowInsets 处理刘海屏
window.decorView.setOnApplyWindowInsetsListener { view, insets ->
val notchHeight = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val displayCutout = insets.displayCutout
displayCutout?.safeInsetTop ?: 0
} else {
0
}
// 设置布局边距
view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = notchHeight
}
insets
}
沉浸式状态栏
// 在 Activity 中
window.apply {
decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
statusBarColor = Color.TRANSPARENT
}
Web 适配方案
CSS 环境变量
:root {
--safe-area-inset-top: env(safe-area-inset-top, 0px);
--safe-area-inset-bottom: env(safe-area-inset-bottom, 0px);
--safe-area-inset-left: env(safe-area-inset-left, 0px);
--safe-area-inset-right: env(safe-area-inset-right, 0px);
}
.container {
padding-top: var(--safe-area-inset-top);
padding-bottom: var(--safe-area-inset-bottom);
}
JavaScript 检测
// 检测是否为刘海屏设备
const hasNotch = () => {
// 方法1:检查屏幕尺寸
const ratio = window.devicePixelRatio || 1;
const screen = {
width: window.screen.width * ratio,
height: window.screen.height * ratio
};
// 方法2:检查 safe area
const div = document.createElement('div');
div.style.cssText = 'padding: env(safe-area-inset-top)';
document.body.appendChild(div);
const hasNotch = parseInt(window.getComputedStyle(div).paddingTop) > 0;
document.body.removeChild(div);
return hasNotch;
};
跨平台框架适配
React Native
import { SafeAreaView, Platform, StatusBar } from 'react-native';
const App = () => (
<SafeAreaView style={{
flex: 1,
paddingTop: Platform.OS === 'ios' ? 0 : StatusBar.currentHeight
}}>
{/* 内容 */}
</SafeAreaView>
);
Flutter
import 'package:flutter/services.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.dark,
child: SafeArea(
child: Scaffold(
// 内容
),
),
);
}
}
Uni-app / Taro 等小程序框架
// 在页面配置中
export default {
style: {
navigationBarTitleText: '页面标题',
navigationStyle: 'custom', // 自定义导航栏
"app-plus": {
titleNView: false // 隐藏原生导航栏
}
},
onLoad() {
// 获取状态栏高度
const { statusBarHeight, safeArea } = uni.getSystemInfoSync();
this.setData({
statusBarHeight,
safeAreaBottom: safeArea.bottom
});
}
}
最佳实践建议
设计原则
- :避开刘海区域
- 交互元素:保持在安全区域内
- 全屏体验:适当处理状态栏颜色
测试策略
// 多设备测试清单
const testDevices = [
'iPhone X/XS/11/12/13/14/15', // 刘海屏
'iPhone 14 Pro/15 Pro', // 灵动岛
'Android 各种异形屏',
'平板设备'
];
工具推荐
- iOS: Xcode 模拟器、Instruments
- Android: Android Studio 模拟器、设备设置中的"开发者选项"
- Web: Chrome DevTools 的设备模拟器
常见问题处理
被遮挡
/* 解决方案:增加顶部内边距 */
.notch-padding {
padding-top: constant(safe-area-inset-top); /* iOS 11.0-11.2 */
padding-top: env(safe-area-inset-top); /* iOS 11.2+ */
}
底部导航栏适配
// 获取底部安全区域高度
const getBottomSafeArea = () => {
if (CSS.supports('padding-bottom: env(safe-area-inset-bottom)')) {
return 'env(safe-area-inset-bottom)';
}
return '0px';
};
横屏模式适配
@media (orientation: landscape) {
.container {
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
}
}
OpenClaw 刘海屏适配的关键在于:

- 理解各平台的差异并针对性处理
- 使用安全区域概念进行布局
- 充分的测试覆盖各种设备
- 保持向后兼容,确保在老设备上也能正常显示
建议在实际开发中根据具体的业务场景和设备要求,选择合适的适配方案。
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。