核心内容摘要
数字时代的感官饕餮:深挖“久草在线观看视频免费高清资源”背后的视觉进化论
前言对于跨平台应用程序处理设备的安全区域Safe Area是一个重要且常见的需求。
不同设备如 iPhone X 系列的刘海屏、Android 的异形屏、HarmonyOS 设备等都有各自的安全区域限制。
react-native-safe-area-context是一个专为 React Native 跨平台应用包括 HarmonyOS设计的安全区域处理库它提供了更强大和灵活的安全区域管理能力支持获取具体的安全区域数值、边缘特定处理等功能。
库简介基本信息库名称:react-native-safe-area-context版本信息:
4.
5: 支持 RN
72 版本react-native-ohos/react-native-safe-area-context
5.
1: 支持 RN
77 版本react-native-ohos/react-native-safe-area-context官方仓库: https://github.com/react-native-oh-library/react-native-safe-area-context主要功能:提供SafeAreaProvider和SafeAreaView组件支持获取设备安全区域边距信息兼容 Android、iOS 和 HarmonyOS 三端兼容性验证:RNOH:
0.
7
26; SDK: HarmonyOS NEXT Developer Beta1; IDE: DevEco Studio
5.
0.
300; ROM:
3.
0.
22RNOH:
0.
7
29; SDK: HarmonyOS NEXT Developer Beta6; IDE: DevEco Studio
5.
0.
700; ROM:
3.
0.
60RNOH:
0.
7
33; SDK: OpenHarmony
5.
0.
71(API Version 12 Release); IDE: DevEco Studio:
5.
0.
900; ROM: NEXT.
0.
71RNOH:
0.
7
18; SDK: HarmonyOS
6.
0.
47 (API Version
; IDE: DevEco Studio
6.
0.
858; ROM:
6.
0.
107为什么需要这个库虽然 React Native 内置了SafeAreaView组件但它存在以下局限性功能单一: 只能提供基本的顶部和底部安全区域处理灵活性不足: 无法获取具体的安全区域数值HarmonyOS 支持: 原生SafeAreaView在 HarmonyOS 上可能表现不一致高级特性缺失: 不支持边缘特定的安全区域处理react-native-safe-area-context解决了这些问题提供了更强大的 API。
安装步骤
使用 npm 安装在项目根目录执行以下命令npminstallreact-native-ohos/react-native-safe-area-context
验证安装安装完成后检查package.json文件应该能看到新增的依赖。
根据您的 RN 版本选择对应的库版本{dependencies:{react-native-ohos/react-native-safe-area-context:
5.
1,// RN
77 版本// 或react-native-ohos/react-native-safe-area-context:
4.
5,// RN
72 版本// ... 其他依赖}} HarmonyOS 平台配置 ⭐由于 HarmonyOS 暂不支持 AutoLink需要手动配置原生端代码。
本文采用方法二直接链接源码的方式。
1 引入原生端代码方法二直接链接源码目前 DevEco Studio 不支持通过源码引入外部 module我们推荐使用直接链接源码的方式将源码通过操作改成 harmony 工程的内部模块。
步骤 1: 把RN工程/node_modules/react-native-ohos/react-native-safe-area-context/harmony目录下的源码safe_area复制到harmony鸿蒙壳工程工程根目录下。
步骤 2: 在harmony工程根目录的build-profile.template.json5若存在和build-profile.json5添加以下模块modules: [ ... { name: xxx, srcPath: ./xxx, }, { name: safe_area, srcPath: ./safe_area, } ]步骤 3: 打开safe_area/oh-package.json5修改react-native-openharmony和项目的版本一致。
步骤 4: 打开entry/oh-package.json5添加以下依赖dependencies: { rnoh/react-native-openharmony:
0.
7
90, react-native-ohos/react-native-safe-area-context: file:../safe_area }步骤 5: 点击 DevEco Studio 右上角的sync按钮2 配置CMakeLists和引入SafeAreaViewPackage若使用的是
4.
5 及以下版本请跳过本章打开entry/src/main/cpp/CMakeLists.txt添加project(rnapp) cmake_minimum_required(VERSION
3.
4.
set(CMAKE_SKIP_BUILD_RPATH TRUE) set(RNOH_APP_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(NODE_MODULES ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../node_modules) set(RNOH_CPP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../react-native-harmony/harmony/cpp) set(LOG_VERBOSITY_LEVEL
set(CMAKE_ASM_FLAGS -Wno-errorunused-command-line-argument -Qunused-arguments) set(CMAKE_CXX_FLAGS -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie) set(WITH_HITRACE_SYSTRACE
# for other CMakeLists.txt files to use add_compile_definitions(WITH_HITRACE_SYSTRACE) add_subdirectory(${RNOH_CPP_DIR} ./rn) # RNOH_BEGIN: manual_package_linking_1 add_subdirectory(../../../../sample_package/src/main/cpp ./sample-package) add_subdirectory(../../../../safe_area/src/main/cpp ./safe-area) # RNOH_END: manual_package_linking_1 file(GLOB GENERATED_CPP_FILES ./generated/*.cpp) add_library(rnoh_app SHARED ${GENERATED_CPP_FILES} ./PackageProvider.cpp ${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp ) target_link_libraries(rnoh_app PUBLIC rnoh) # RNOH_BEGIN: manual_package_linking_2 target_link_libraries(rnoh_app PUBLIC rnoh_sample_package) target_link_libraries(rnoh_app PUBLIC rnoh_safe_area) # RNOH_END: manual_package_linking_2打开entry/src/main/cpp/PackageProvider.cpp添加#include RNOH/PackageProvider.h #include generated/RNOHGeneratedPackage.h #include SamplePackage.h #include SafeAreaViewPackage.h using namespace rnoh; std::vectorstd::shared_ptrPackage PackageProvider::getPackages(Package::Context ctx) { return { std::make_sharedRNOHGeneratedPackage(ctx), std::make_sharedSamplePackage(ctx), std::make_sharedSafeAreaViewPackage(ctx), }; }3 在ArkTs侧引入SafeAreaViewPackage修改 entry/src/main/ets/RNPackagesFactory.tsimport{SafeAreaViewPackage}fromreact-native-ohos/react-native-safe-area-context/ts;exportfunctioncreateRNPackages(ctx:RNPackageContext):RNPackage[]{return[// ... 其他包newSafeAreaViewPackage(ctx),];} 完整代码示例下面是一个完整的示例展示了react-native-safe-area-context的各种使用场景importReactfromreact;import{View,Text,StyleSheet,ScrollView,TouchableOpacity,StatusBar}fromreact-native;import{SafeAreaProvider,SafeAreaView,useSafeAreaInsets,useSafeAreaFrame,initialWindowMetrics,}fromreact-native-safe-area-context;functionSafeAreaDemo(){return(SafeAreaProvider initialMetrics{initialWindowMetrics}MainApp//SafeAreaProvider);}functionMainApp(){constisDarkModefalse;constbackgroundStyle{backgroundColor:isDarkMode?#121212:#f5f5f5,};return(View style{[backgroundStyle,{flex:1}]}StatusBar barStyle{isDarkMode?light-content:dark-content}/ScrollView contentContainerStyle{styles.scrollContent}{/* 示例 1: 基础使用 */}View style{styles.section}Text style{styles.sectionTitle}
基础 SafeAreaView/TextSafeAreaView style{styles.basicSafeArea}Text style{styles.text}这个视图自动处理安全区域/Text/SafeAreaView/View{/* 示例 2: 指定边缘 */}View style{styles.section}Text style{styles.sectionTitle}
只处理顶部和底部/TextSafeAreaView style{styles.edgeSafeArea}edges{[top,bottom]}View style{styles.content}Text style{styles.text}顶部和底部有安全区域/TextText style{styles.text}左右没有安全区域/Text/View/SafeAreaView/View{/* 示例 3: 嵌套使用 */}View style{styles.section}Text style{styles.sectionTitle}
嵌套 SafeAreaView/TextSafeAreaView style{styles.outerSafeArea}edges{[top]}Text style{styles.text}外层处理顶部/TextSafeAreaView style{styles.innerSafeArea}edges{[bottom]}Text style{styles.text}内层处理底部/Text/SafeAreaView/SafeAreaView/View{/* 示例 4: 使用 useSafeAreaInsets Hook */}View style{styles.section}Text style{styles.sectionTitle}
useSafeAreaInsets Hook/TextInsetsExample//View{/* 示例 5: 使用 useSafeAreaFrame Hook */}View style{styles.section}Text style{styles.sectionTitle}
useSafeAreaFrame Hook/TextFrameExample//View{/* 示例 6: 自定义样式 */}View style{styles.section}Text style{styles.sectionTitle}
自定义样式/TextCustomStyledExample//View/ScrollView/View);}// Hook 示例使用 useSafeAreaInsetsfunctionInsetsExample(){constinsetsuseSafeAreaInsets();return(View style{[styles.insetsContainer,{paddingTop:insets.top,paddingBottom:insets.bottom,paddingLeft:insets.left,paddingRight:insets.right,},]}Text style{styles.text}顶部边距:{insets.top}/TextText style{styles.text}底部边距:{insets.bottom}/TextText style{styles.text}左边距:{insets.left}/TextText style{styles.text}右边距:{insets.right}/Text/View);}// Hook 示例使用 useSafeAreaFramefunctionFrameExample(){constframeuseSafeAreaFrame();return(View style{styles.insetsContainer}Text style{styles.text}屏幕宽度:{frame.width}/TextText style{styles.text}屏幕高度:{frame.height}/TextText style{styles.text}X坐标:{frame.x}/TextText style{styles.text}Y坐标:{frame.y}/Text/View);}// 自定义样式示例functionCustomStyledExample(){const[selectedEdge,setSelectedEdge]React.useState(top);constedges[top,bottom,left,right];return(ViewView style{styles.edgeButtons}{edges.map((edge)(TouchableOpacity key{edge}style{[styles.edgeButton,selectedEdgeedgestyles.selectedEdgeButton,]}onPress{()setSelectedEdge(edge)}Text style{styles.edgeButtonText}{edge}/Text/TouchableOpacity))}/ViewSafeAreaView style{styles.customSafeArea}edges{[selectedEdgeasany]}Text style{styles.text}当前处理边缘:{selectedEdge}/Text/SafeAreaView/View);}conststylesStyleSheet.create({scrollContent:{padding:20,},section:{marginBottom:30,},sectionTitle:{fontSize:18,fontWeight:bold,marginBottom:10,},basicSafeArea:{backgroundColor:#4c669f,padding:20,borderRadius:8,},edgeSafeArea:{backgroundColor:#3b5998,padding:20,borderRadius:8,minHeight:100,},outerSafeArea:{backgroundColor:#192f6a,padding:20,borderRadius:8,},innerSafeArea:{backgroundColor:#4c669f,padding:20,borderRadius:8,marginTop:10,},content:{minHeight:100,},insetsContainer:{backgroundColor:#e74c3c,padding:20,borderRadius:8,},customSafeArea:{backgroundColor:#2ecc71,padding:20,borderRadius:8,minHeight:100,},edgeButtons:{flexDirection:row,flexWrap:wrap,marginBottom:10,},edgeButton:{backgroundColor:#95a5a6,paddingHorizontal:15,paddingVertical:8,borderRadius:5,marginRight:8,marginBottom:8,},selectedEdgeButton:{backgroundColor:#3498db,},edgeButtonText:{color:white,fontWeight:bold,},text:{color:white,fontSize:16,marginBottom:5,},});exportdefaultSafeAreaDemo;
执行npm run harmony命令执行npm run harmony命令构建适用于鸿蒙的 bundle 文件并拷贝到鸿蒙工程rawfile目录下。
实际应用场景完整示例代码已展示了以下实际应用场景基础使用: 使用SafeAreaView自动处理安全区域边缘指定: 使用edges属性指定需要处理的边缘嵌套使用: 多个SafeAreaView嵌套使用处理不同区域获取安全区域数值: 使用useSafeAreaInsetsHook 获取具体的边距数值获取屏幕信息: 使用useSafeAreaFrameHook 获取屏幕尺寸信息动态切换: 通过状态动态切换处理的边缘⚠️
注意事项与最佳实践
SafeAreaProvider 的位置SafeAreaProvider应该放在应用的最外层通常包裹整个App组件// ✅ 正确SafeAreaProviderApp//SafeAreaProvider// ❌ 错误 - 放在组件内部functionApp(){return(ViewSafeAreaProvider{/* 内容 */}/SafeAreaProvider/View);}
initialWindowMetrics 的使用initialWindowMetrics用于提供初始的安全区域度量有助于避免首次渲染时的布局闪烁SafeAreaProvider initialMetrics{initialWindowMetrics}{/* 内容 */}/SafeAreaProvider
性能考虑SafeAreaView会在每次安全区域变化时重新渲染如果内容复杂考虑使用React.memo优化避免在SafeAreaView内部使用过多的嵌套组件对于不需要处理安全区域的 View不要使用SafeAreaView
HarmonyOS 特殊处理在 HarmonyOS 平台上确保已正确配置原生端代码参考上述 HarmonyOS 配置步骤测试不同设备的安全区域表现注意 HarmonyOS 设备可能的安全区域差异
与 StatusBar 的配合SafeAreaView会自动处理状态栏区域通常不需要额外设置StatusBar的translucent属性// ✅ 推荐SafeAreaView styleStatusBar barStyledark-content/{/* 内容 */}/SafeAreaView// ⚠️ 如果使用 translucent需要额外处理StatusBar translucent/SafeAreaView style{/* 内容 */}/SafeAreaView
样式继承SafeAreaView本质上是一个View支持所有View的样式属性SafeAreaView style{/* 内容 */}/SafeAreaView
总结通过集成react-native-safe-area-context我们为项目添加了强大的安全区域处理能力。
这个库不仅解决了跨平台安全区域处理的痛点还提供了灵活的 API 来满足各种复杂的布局需求。
欢迎加入开源鸿蒙跨平台社区https://openharmonycrossplatform.csdn.net