@hadss/react_native_folderstack
v1.0.0-rc.2
Published
这是一个旨在解决 React Native多设备适配问题的三方库,专为不同设备类型(包括折叠屏、平板、手机等)提供了便捷的支持。该库包含的接口和开箱即用的组件,使开发者能够轻松应对各种设备的布局适配需求。
Readme
@hadss/react_native_folderstack
介绍
这是一个旨在解决 React Native多设备适配问题的三方库,专为不同设备类型(包括折叠屏、平板、手机等)提供了便捷的支持。该库包含的接口和开箱即用的组件,使开发者能够轻松应对各种设备的布局适配需求。
目前该库提供的组件如下:
- 折叠屏相关组件:基于ArkUI折叠屏相关接口开发的RN获取折叠屏信息的接口,包括折叠屏状态、是否是折叠屏、折叠屏避让区域信息及监听折叠屏变化等能力。
- 自适应显隐容器:对标ArkUI的自适应显隐布局开发的容器,使开发者能够轻松的完成自适应显隐布局能力的开发。
- 侧边栏组件:对标ArkUI的SideBarContainer组件开发的RN侧边栏组件,使开发者能够轻松的完成侧边栏相关布局能力的开发。
- 自适应分栏组件:参考ArkUI的Navigation组件开发的RN分栏组件,使开发者能够轻松的完成分栏及路由跳转能力的开发。
- 栅格组件:对标ArkUI的GridRow/GridCol开发的RN栅格组件,提供基础的栅格布局能力,使开发能够直接使用ArkUI栅格布局能力。
工程目录
.
├─harmony
│ ├─folder_stack.har // Turbo Modules接口har包
│ └─folder_stack
│ └─src/main/ets
│ ├─FolderStackModule.ets // Turbo Modules接口ArkTS实现
│ ├─FolderStackModulePackage.ets // FolderStackModulesFactory
│ ├─FolderStackModuleSpec.ts // Turbo Modules接口,提供折叠屏相关接口
│ └─core
│ └─FoldConfig.ts
├─src
│ ├─index.ts // RN模块导出
│ ├─component
│ │ ├─FoldSplitContainer // 折叠屏高阶组件FoldSplitContainer
| | └─FoldStack // 折叠屏高阶组件FoldStack
│ ├─turbo
│ | └─FolderStackModule.ts // Turbo Modules接口
│ └─utils
│ ├─FoldUtils // 封装折叠屏相关接口
│ └─ThrottleUtils // 节流(throttle)函数的 TypeScript 实现,用于限制某个函数的执行频率,确保它在指定的时间间隔内最多执行一次。安装与使用
进入到工程目录并输入以下命令:
npm
npm install @hadss/react_native_folderstackyarn
yarn add @hadss/react_native_folderstack下面的代码展示了这个库的基本使用场景:
FoldSplitContainer使用示例
import { Fold, ExpandedRegionLayoutOptions, ExtraRegionPosition, HoverModeRegionLayoutOptions, FoldSplitContainer } from "@hadss/react_native_folderstack";
import React, { useState, useEffect } from "react";
import { View, Text, Button, StyleSheet } from "react-native";
const TestSample = () => {
const [foldCreaseRegion, setFoldCreaseRegion] = useState<number[]>([]);
const [foldStatus, setFoldStatus] = useState('');
const [isDeviceFoldable, setIsDeviceFoldable] = useState(false);
useEffect(() => {
const checkFoldable = () => {
// 判断当前设备是否可折叠
const foldable = Fold.isFoldable();
setIsDeviceFoldable(foldable);
if (foldable) {
// 获取折痕区域
setFoldCreaseRegion(Fold?.getFoldCreaseRegion()==null ?[]:Fold?.getFoldCreaseRegion()[0]);
// 获取当前折叠屏状态
setFoldStatus(Fold.getFoldStatus());
}
};
checkFoldable();
// 监听折叠屏状态变化
Fold.addFoldListener((foldStatus) => {
console.log('折叠屏状态发生变化', foldStatus);
});
return () => {
// 销毁监听折叠屏状态变化
Fold.removeFoldListener();
};
}, []);
const handleGetFoldStatus = () => {
if (isDeviceFoldable) {
// 获取当前折叠屏状态
setFoldStatus(Fold.getFoldStatus());
}
};
// FoldSplitContainer 主要区域
const primaryRender = () => (
<View style={{ flex: 1 }}>
<Text>Is Device Foldable: {isDeviceFoldable ? 'Yes' : 'No'}</Text>
{isDeviceFoldable && (
<>
<Text>Fold Crease Region: {JSON.stringify(foldCreaseRegion)}</Text>
<Button title="Get Fold Status" onPress={handleGetFoldStatus} />
{foldStatus && <Text>Fold Status: {foldStatus}</Text>}
</>
)}
</View>
);
// FoldSplitContainer 次要区域
const secondRender = () => (
<View style={{ flex: 1, backgroundColor: 'blue' }}>
<Text style={{ fontSize: 20 }}>secondRender</Text>
</View>
);
// FoldSplitContainer 扩展区域
const extraRender = () => (
<View style={{ flex: 1, backgroundColor: 'red' }}>
<Text style={{ fontSize: 20 }}>extraRender</Text>
</View>
);
// 折叠屏展开态配置
const expandedLayoutOptions: ExpandedRegionLayoutOptions = {
isExtraRegionPerpendicular: false,
extraRegionPosition: ExtraRegionPosition.BOTTOM,
};
// 折叠屏悬停态配置
const hoverModeRegionLayoutOptions: HoverModeRegionLayoutOptions = {
showExtraRegion: true,
};
return (
<View style={styles.container}>
<FoldSplitContainer
primary={primaryRender()}
secondary={secondRender()}
extra={extraRender()}
expandedLayoutOptions={expandedLayoutOptions}
hoverModeLayoutOptions={hoverModeRegionLayoutOptions}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
export default TestSample;FoldStack使用示例
import React from 'react';
import {
View,
Text,
StyleSheet,
} from 'react-native';
import { FolderStack } from '@hadss/react_native_folderstack';
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'rgb(39, 135, 217)'
},
videoContainer: {
width: '100%',
height: '100%',
justifyContent: 'center',
backgroundColor: 'rgb(100, 135, 217)'
},
videoText: {
fontSize: 25,
color: 'white',
textAlign: 'center'
},
controlBar: {
height: '100%',
width: '100%',
},
controlText: {
fontSize: 25,
textAlign: 'center',
width: '100%',
height: 50
}
});
const FolderStackDemo = () => {
return (
<View style={[styles.videoContainer]}>
<FolderStack
upperItems={["upperitemsId"]}
enableAnimation={true}
autoHalfFold={true}
alignContent='End'
onFolderStateChange={(foldStatus) => {
console.log(`onFolderStateChange params is ${JSON.stringify(foldStatus)}`)
}
}
onHoverStatusChange={(HoverStatus) => {
console.log(`onHoverStatusChange params is ${JSON.stringify(HoverStatus)}`)
}
}
>
{/* 上半屏视频区域 */}
<View style={[styles.videoContainer, { backgroundColor: 'rgb(0, 74, 175)' }]} id="upperitemsId">
<Text style={styles.videoText}>video zone</Text>
</View>
{/* 下半屏操作区域 */}
<View style={[styles.controlBar, { justifyContent: 'flex-start' }]} id="2">
<Text style={[styles.controlText, { backgroundColor: 'rgb(213, 213, 213)' }]}>video title</Text>
</View>
<View style={[styles.controlBar, { justifyContent: 'flex-end', zIndex: 5 }]} id="3">
<Text style={[styles.controlText, { backgroundColor: 'rgb(213, 213, 213)' }]}>video bar</Text>
</View>
</FolderStack>
</View>
);
};
export default FolderStackDemo;
Link
本库依赖以下三方库,请查看对应文档:
目前OpenHarmony暂不支持AutoLink,所以Link步骤需要手动配置。
首先需要使用DevEco Studio打开项目里的OpenHarmony工程,在工程根目录的oh-package.json5添加overrides字段:
{
...
"overrides": {
"@rnoh/react-native-openharmony" : "./react_native_openharmony"
}
}引入原生端代码
目前有两种方法:
通过har包引入(在IDE完善相关功能后该方法会被遗弃,目前首选此方法)。
说明: har包位于三方库安装路径的
harmony文件夹下。a. 打开
entry/oh-package.json5,添加以下依赖:"dependencies": { "@rnoh/react-native-openharmony": "file:../react_native_openharmony", "@hadss/react_native_folderstack": "file:../../node_modules/@hadss/react_native_folderstack/harmony/folder_stack.har", }b. 配置CMakeLists和引入RNOHGeneratedPackage:
打开
entry/src/main/cpp/CMakeLists.txt,添加:project(rnapp) cmake_minimum_required(VERSION 3.4.1) set(CMAKE_SKIP_BUILD_RPATH TRUE) set(OH_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules") set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}") set(RNOH_CPP_DIR "${OH_MODULE_DIR}/@rnoh/react-native-openharmony/src/main/cpp") set(RNOH_GENERATED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/generated") set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments") set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie") add_compile_definitions(WITH_HITRACE_SYSTRACE) set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to use + file(GLOB GENERATED_CPP_FILES "./generated/*.cpp") add_subdirectory("${RNOH_CPP_DIR}" ./rn) add_library(rnoh_app SHARED + ${GENERATED_CPP_FILES} "./PackageProvider.cpp" "${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp" ) target_link_libraries(rnoh_app PUBLIC rnoh)c. 打开
entry/src/main/cpp/PackageProvider.cpp,添加:#include "RNOH/PackageProvider.h" + #include "generated/RNOHGeneratedPackage.h" using namespace rnoh; std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) { return { + std::make_shared<RNOHGeneratedPackage>(ctx) }; }d. 在ArkTs侧引入FolderStackModulePackage:
打开
entry/src/main/ets/RNPackagesFactory.ts,添加:... + import { FolderStackModulePackage } from '@hadss/react_native_folderstack/ts'; export function createRNPackages(ctx: RNPackageContext): RNPackage[] { return [ + new FolderStackModulePackage(ctx), ]; }e. 运行:
点击右上角的
sync按钮或者在终端执行:
cd entry ohpm install然后编译、运行即可。
说明 若项目启动时报错:can not find record '&@rnoh/react-native-openharmony/generated/ts&X.X.X'。需在entry\oh_modules@rnoh\react-native-openharmony\ts.ts文件中添加export * from './generated/ts',并删除.cxx文件夹、build文件夹,然后执行sync操作同步代码。
直接链接源码。
如需使用直接链接源码,请参考直接链接源码说明。
API
说明: "Platform"列表示支持的平台,All表示支持所有平台。
折叠屏适配
折叠屏接口
| Name | Description | Type | Platform |
| ------------------- | ------------------------------------------------------------ | -------- | --------- |
| getFoldCreaseRegion | 获取可折叠设备屏幕的折痕区域。 | function | OpenHarmony |
| getFoldStatus | 获取当前可折叠设备的状态(例如:展开、半折叠或折叠)。 | function | OpenHarmony |
| isFoldable | 判断设备是否可折叠。如果为 true,设备是可折叠的;否则是不可折叠设备。 | function | OpenHarmony |
| addFoldListener | 监听折叠设备的折叠状态变化。 | function | OpenHarmony |
| removeFoldListener | 移除已添加的折叠状态变化监听。 | function | OpenHarmony |
FoldSplitContainer组件
| Name | Description | Type | Platform | | :--------------------- | :--------------------------------------------- | :--------------------------- | :-------- | | primary | 主要区域回调函数。 | function | OpenHarmony | | secondary | 次要区域回调函数。 | function | OpenHarmony | | extra | 扩展区域回调函数,不传入的情况,没有对应区域。 | function | OpenHarmony | | expandedLayoutOptions | 展开态布局信息。 | ExpandedRegionLayoutOptions | OpenHarmony | | hoverModeLayoutOptions | 悬停态布局信息。 | HoverModeRegionLayoutOptions | OpenHarmony | | foldedLayoutOptions | 折叠态布局信息。 | FoldedRegionLayoutOptions | OpenHarmony | | onHoverStatusChange | 折叠屏进入或退出悬停模式时触发的回调函数。 | onHoverStatusChangeHandler | OpenHarmony |
FoldStack组件
| Name | Description | Type | Platform | | :--------------------- | :--------------------------------------------- | :--------------------------- | :-------- | | upperItems | 主要区域回调函数。 | string[] | OpenHarmony | | enableAnimation | 动画是否开启。 | boolean | OpenHarmony | | alignContent | 布局形式。 | Alignment | OpenHarmony | | autoHalfFold | 自动旋转开关。 | boolean | OpenHarmony | | onFolderStateChange | 折叠屏状态变化触发的回调函数。 | (event: { foldStatus: FoldStatus }) => void | OpenHarmony | | onHoverStatusChange | 折叠屏进入或退出悬停模式时触发的回调函数。 | onHoverStatusChangeHandler | OpenHarmony |
ExpandedRegionLayoutOptions
| Name | Description | Type | Platform | | :------------------------- | :----------------------------------------------------------- | :------------------ | --------- | | isExtraRegionPerpendicular | 扩展区域是否从上到下贯穿整个组件,当且仅当extra有效时此字段才生效。默认值:true。 | boolean | OpenHarmony | | verticalSplitRatio | 主要区域与次要区域之间的高度比例。默认值:PresetSplitRatio.LAYOUT_1V1。 | number | OpenHarmony | | horizontalSplitRatio | 主要区域与扩展区域之间的宽度比例,当且仅当extra有效时此字段才生效。默认值:PresetSplitRatio.LAYOUT_3V2。 | number | OpenHarmony | | extraRegionPosition | 扩展区域的位置信息,当且仅当isExtraRegionPerpendicular = false有效时此字段才生效。默认值:ExtraRegionPosition.top。 | ExtraRegionPosition | OpenHarmony |
HoverModeRegionLayoutOptions
| Name | Description | Type | Platform | | :------------------- | :----------------------------------------------------------- | :------------------ | :-------- | | showExtraRegion | 可折叠屏幕在半折叠状态下是否显示扩展区域。默认值:false。 | boolean | OpenHarmony | | horizontalSplitRatio | 主要区域与扩展区域之间的宽度比例,当且仅当extra有效时此字段才生效。默认值:PresetSplitRatio.LAYOUT_3V2。 | number | OpenHarmony | | extraRegionPosition | 扩展区域的位置信息,当且仅当showExtraRegion时此字段才生效。默认值:ExtraRegionPosition.top。 | ExtraRegionPosition | OpenHarmony |
FoldedRegionLayoutOptions
| Name | Description | Type | Platform | | :----------------- | :----------------------------------------------------------- | :----- | :-------- | | verticalSplitRatio | 主要区域与次要区域之间的高度比例。默认值:PresetSplitRatio.LAYOUT_1V1。 | number | OpenHarmony |
onHoverStatusChangeHandler
| Name | Description | Type | Platform | | :------- | :----------------------------------------- | :-------------------------------- | :-------- | | callback | 折叠屏进入或退出悬停模式时触发的回调函数。 | (status: HoverModeStatus) => void | OpenHarmony |
HoverModeStatus
| Name | Description | Type | Platform | | :---------- | :---------------------- | :--------- | :-------- | | foldStatus | 设备的折叠状态。 | FoldStatus | OpenHarmony | | isHoverMode | app当前是否处于悬停态。 | boolean | OpenHarmony | | appRotation | AppRotation。 | AppRotation | OpenHarmony |
AppRotation
| Name | Description | Value | | :----- | :----------------------- | :---- | | ROTATION_0 | 应用方向为0度。 | 0 | | ROTATION_90 | 应用方向为90度。 | 1 | | ROTATION_180 | 应用方向为180度。 | 2 | | ROTATION_270 | 应用方向为270度。 | 3 |
ExtraRegionPosition
| Name | Description | Value | | :----- | :----------------------- | :---- | | top | 扩展区域在组件上半区域。 | 1 | | bottom | 扩展区域在组件下半区域。 | 2 |
PresetSplitRatio
| Name | Description | Value | | :--------- | :---------- | :---- | | LAYOUT_1V1 | 1:1比例。 | 1/1 | | LAYOUT_3V2 | 3:2比例。 | 3/2 | | LAYOUT_2V3 | 2:3比例。 | 2/3 |
约束与限制
系统与设备:本示例仅支持在标准系统的华为手机上运行。 开发环境:需要DevEco Studio 5.0.1 Release或更高版本。 功能与SDK版本对应关系: 双折叠的悬停适配:需要SDK API 12及以上版本。 三折叠的悬停适配:需要SDK API 15及以上版本。
