Gathering detailed insights and metrics for @hadss/react_native_geometry_transition
Gathering detailed insights and metrics for @hadss/react_native_geometry_transition
Gathering detailed insights and metrics for @hadss/react_native_geometry_transition
Gathering detailed insights and metrics for @hadss/react_native_geometry_transition
npm install @hadss/react_native_geometry_transition
Typescript
Module System
Node Version
NPM Version
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
3
为基于 React Native 的混合开发工程提供一镜到底能力。
.
├── harmony
│ ├── geometry_transition
│ │ ├── src
│ │ │ └── main
│ │ │ ├── cpp // CAPI一镜到底组件实现
│ │ │ │ ├── CMakeLists.txt
│ │ │ │ ├── GeometryViewComponentDescriptor.h
│ │ │ │ ├── GeometryViewComponentInstance.cpp
│ │ │ │ ├── GeometryViewComponentInstance.h
│ │ │ │ ├── GeometryViewEventEmitter.cpp
│ │ │ │ ├── GeometryViewEventEmitter.h
│ │ │ │ ├── GeometryViewJSIBinder.h
│ │ │ │ ├── GeometryViewNode.cpp
│ │ │ │ ├── GeometryViewNode.h
│ │ │ │ ├── GeometryViewPackage.cpp
│ │ │ │ ├── GeometryViewPackage.h
│ │ │ │ ├── Index.d.ts
│ │ │ │ ├── Props.cpp
│ │ │ │ ├── Props.h
│ │ │ │ └── oh-package.json5
│ │ │ ├── ets // ArkTS一镜到底组件实现
│ │ │ │ ├── GeometryTransitionView.ets
│ │ │ │ ├── GeometryTransitionViewPackages.ts
│ │ │ │ └── generated
│ │ │ │ ├── components
│ │ │ │ │ ├── GeometryTransitionView.ts
│ │ │ │ │ └── ts.ts
│ │ │ │ ├── index.ets
│ │ │ │ ├── ts.ts
│ │ │ │ └── turboModules
│ │ │ │ └── ts.ts
│ │ │ └── module.json5
│ │ └── ts.ts
│ └── geometry_transition.har
├── package.json
├── src
│ ├── fabric
│ │ ├── GeometryView.tsx // CAPI一镜到底组件
│ │ └── v1
│ │ └── GeometryTransitionViewNativeComponent.tsx // ArkTS一镜到底组件
│ └── index.tsx
进入到工程目录并输入以下命令:
npm
1npm install @hadss/react_native_geometry_transition
yarn
1yarn add @hadss/react_native_geometry_transition
下面的代码展示了这个库的基本使用场景: 前置条件:ArkUI的navigation控制路由跳转,NavDestination加载对应的RN bundle。
场景一:当前页面是RN页面,目标页面是原生页面
PlayList页面
使用了GeometryView组件,并设置了geometryViewID为'test',点击事件调用原生navPathStack.pushPath,跳转MusicPlay页面。
1function PlayList() { 2 return ( 3 <SafeAreaView style={styles.container}> 4 <GeometryView 5 style={[styles.geometryView, { top: 100, left: 100 }]} 6 geometryViewID={'test'} 7 onGeometryViewClick={() => { 8 SampleTurboModule.pushStringToHarmony('pages/MusicPlay', 1); 9 }} 10 /> 11 </SafeAreaView> 12 ); 13} 14 15const styles = StyleSheet.create({ 16 container: { 17 flex: 1, 18 backgroundColor: '#fff', 19 justifyContent: 'center', 20 alignItems: 'center', 21 width: '100%', 22 height: '100%', 23 }, 24 geometryView: { 25 position: 'absolute', 26 width: 60, 27 height: 60, 28 backgroundColor: 'red', 29 }, 30}); 31 32export default PlayList;
MusicPlay页面
1function MusicPlay() { 2 return ( 3 <SafeAreaView style={styles.container}> 4 <GeometryView style={{ width: 200, height: 200, backgroundColor: 'red' }} geometryViewID={'test'} onGeometryViewClick={() => { 5 SampleTurboModule.pushStringToHarmony('pop', 2) 6 }} > 7 </GeometryView> 8 </SafeAreaView> 9 ); 10} 11 12const styles = StyleSheet.create({ 13 container: { 14 flex: 1, 15 backgroundColor: '#fff', 16 justifyContent: 'center', 17 alignItems: 'center', 18 width: '100%', 19 height: '100%' 20 }, 21 text: { 22 fontSize: 18, 23 color: '#333', 24 }, 25}); 26 27export default MusicPlay;
原生侧
PlayListPage监听RN页面跳转事件,如果事件触发,调用this.navPathStack.pushPath({ name: 'MusicPlayPage' }),跳转至原生MusicPlayPage页面。
1@Component 2export default struct PlayListPage { 3 private instance: RNInstance = LoadManager.instance; 4 private bundlePath = 'bundle/playlist.harmony.bundle' 5 private moduleName = 'PlayList' 6 @StorageLink('isMetroAvailable') isMetroAvailable: boolean = false 7 @Consume('navPathStack') navPathStack: NavPathStack 8 9 aboutToAppear() { 10 emitter.on({ eventId: 1 }, () => { 11 animateTo({duration: 700, curve: Curve.Friction}, () => { 12 this.navPathStack.pushPath({ name: 'MusicPlayPage' }) 13 }); 14 }); 15 } 16 17 aboutToDisappear() { 18 emitter.off(1); 19 } 20 21 build() { 22 NavDestination() { 23 if (this.isMetroAvailable) { 24 MetroBaseRN({ 25 moduleName: this.moduleName, 26 }).align(Alignment.Top).margin({ top: 0 }) 27 } else if (this.instance) { 28 BaseRN({ 29 rnInstance: this.instance, 30 moduleName: this.moduleName, 31 bundlePath: this.bundlePath, 32 }).align(Alignment.Top).margin({ top: 0 }) 33 } else { 34 Text('加载失败') 35 } 36 } 37 .hideTitleBar(true) 38 } 39}
MusicPlayPage加载RN侧MusicPlay页面
1@Component 2export default struct MusicPlayPage { 3 private instance: RNInstance = LoadManager.instance 4 private bundlePath = 'bundle/musicplay.harmony.bundle' 5 private moduleName = 'MusicPlay' 6 @StorageLink('isMetroAvailable') isMetroAvailable: boolean = false 7 @Consume('navPathStack') navPathStack: NavPathStack 8 9 aboutToAppear() { 10 emitter.on({ eventId: 2 }, () => { 11 animateTo({duration: 700, curve: Curve.Friction}, () => { 12 this.navPathStack.pop() 13 }); 14 }); 15 } 16 17 aboutToDisappear() { 18 emitter.off(2); 19 } 20 21 build() { 22 NavDestination() { 23 if (this.isMetroAvailable) { 24 MetroBaseRN({ 25 moduleName: this.moduleName, 26 }) 27 .align(Alignment.Top).margin({ top: 20 }) 28 } else if (this.instance) { 29 BaseRN({ 30 rnInstance: this.instance, 31 moduleName: this.moduleName, 32 bundlePath: this.bundlePath, 33 }).align(Alignment.Top).margin({ top: 20 }) 34 } else { 35 Text('加载失败') 36 } 37 } 38 .geometryTransition('test') // 设置同RN侧一致的id 39 .hideTitleBar(true) 40 } 41} 42
场景二:当前页面和目标页面均是RN页面
RN侧当前页面
使用了GeometryTransitionView组件,并设置了geometryViewID为'test',pageType设置为'current',点击跳转按钮调用原生navPathStack.pushPath,跳转至目标页面。
Tip: duration动画执行时间在当前页面设置不会生效,具体动画执行时间由目标页面的duration控制。
1 <View style={{ width: '100%', height: '100%', justifyContent: 'center', alignItems: 'center' }}> 2 <GeometryTransitionView geometryViewID='test' style={{ width: 100, height: 100, backgroundColor: 'black' }} isFollow={false} duration={700} pageType={'current'}> 3 </GeometryTransitionView> 4 <Button title="跳转" onPress={() => { SampleTurboModule.pushStringToHarmony('pages/TargetPage', 1); }}></Button> 5 </View>
原生侧当前页面
监听路由跳转事件,跳转至目标页面。
1 aboutToAppear() { 2 emitter.on({ eventId: 1 }, (eventData) => { 3 this.pagePathsGoods.pushPath({ name: "TargetPage" }, false); 4 }); 5 }
RN侧目标页面
使用了GeometryTransitionView组件,并设置了与 “当前页面“ 一致的geometryViewID:'test',pageType设置为'target',duration为设置从 “当前页面“ 跳转至目标页面的动画执行时间,点击返回按钮调用原生navPathStack.pop,返回 “当前页面“ 。
1 <View style={{ width: '100%', height: '50%', justifyContent: 'flex-end', alignItems: 'center', paddingBottom: '120' }}> 2 <GeometryTransitionView 3 style={{ width: 200, height: 200, backgroundColor: 'red' }} 4 geometryViewID={'test'} 5 isFollow={false} 6 duration={700} 7 pageType={'target'} 8 > 9 </GeometryTransitionView> 10 <Button title="返回" onPress={() => { SampleTurboModule.pushStringToHarmony('pages/CurrentPage', 2); }}></Button> 11 </View>
原生侧目标页面
监听路由返回事件,使用动画返回跳转至 “当前页面“ 。
1 aboutToAppear() { 2 emitter.on({ eventId: 2 }, (eventData) => { 3 if (eventData.data) { 4 const path: string = eventData.data['param']; 5 if (path === "pages/CurrentPage") { 6 animateTo({ duration: 700 }, () => { 7 this.pagePathsGoods.pop(false); 8 }) 9 } 10 } 11 }); 12 }
目前OpenHarmony暂不支持AutoLink,所以Link步骤需要手动配置。
首先需要使用DevEco Studio打开项目里的OpenHarmony工程,在工程根目录的 oh-package.json5
添加 overrides 字段:
1{ 2 ... 3 "overrides": { 4 "@rnoh/react-native-openharmony" : "./react_native_openharmony" 5 } 6}
目前有两种方法:
方法一:
通过har包引入(在IDE完善相关功能后该方法会被遗弃,目前首选此方法)
说明: har包位于三方库安装路径的
harmony
文件夹下。
a.打开entry/oh-package.json5
,添加以下依赖:
1"dependencies": { 2 "@rnoh/react-native-openharmony": "file:../react_native_openharmony", 3 "@hadss/react_native_geometry_transition": "file:../../node_modules/@hadss/react_native_geometry_transition/harmony/geometry_transition.har", 4 }
b.配置CMakeLists和引入GeometryViewPackage:
打开entry/src/main/cpp/CMakeLists.txt
,添加:
1project(rnapp) 2cmake_minimum_required(VERSION 3.4.1) 3set(CMAKE_SKIP_BUILD_RPATH TRUE) 4set(OH_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules") 5set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}") 6 7set(RNOH_CPP_DIR "${OH_MODULE_DIR}/@rnoh/react-native-openharmony/src/main/cpp") 8set(RNOH_GENERATED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/generated") 9set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments") 10set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie") 11add_compile_definitions(WITH_HITRACE_SYSTRACE) 12set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to use 13+ add_subdirectory("${OH_MODULE_DIR}/@hadss/react_native_geometry_transition/src/main/cpp" ./geometry_transition) 14 15add_subdirectory("${RNOH_CPP_DIR}" ./rn) 16 17add_library(rnoh_app SHARED 18 "./PackageProvider.cpp" 19 "${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp" 20) 21 22target_link_libraries(rnoh_app PUBLIC rnoh) 23+ target_link_libraries(rnoh_app PUBLIC geometry_transition)
c.打开entry/src/main/cpp/PackageProvider.cpp
,添加:
1#include "RNOH/PackageProvider.h" 2+ #include "GeometryViewPackage.h" 3 4using namespace rnoh; 5 6std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) { 7 return { 8+ std::make_shared<GeometryViewPackage>(ctx) 9 }; 10}
d.运行:
点击右上角的sync
按钮
或者在终端执行:
1cd entry 2ohpm install
然后编译、运行即可。
在 ArkTS 侧引入 GeometryTransitionView
1 ... 2+ import { GeometryTransitionView } from '@hadss/react_native_geometry_transition'; 3 4 @Builder 5 export function buildCustomRNComponent(ctx: ComponentBuilderContext) { 6 ... 7+ if (ctx.componentName === GeometryTransitionView.NAME) { 8+ GeometryTransitionView({ 9+ ctx: ctx.rnComponentContext, 10+ tag: ctx.tag 11+ }) 12+ } 13... 14} 15...
在entry/src/main/ets/pages/index.ets
或 entry/src/main/ets/rn/LoadBundle.ets
找到常量 arkTsComponentNames
在其数组里添加组件名
1const arkTsComponentNames: Array<string> = [ 2 SampleView.NAME, 3 GeneratedSampleView.NAME, 4 PropsDisplayer.NAME, 5+ GeometryTransitionView.NAME 6 ];
在 ArkTS 侧引入 GeometryTransitionViewPackage
1 ... 2+ import { GeometryTransitionViewPackage } from '@hadss/react_native_geometry_transition/ts'; 3 4export function createRNPackages(ctx: RNPackageContext): RNPackage[] { 5 return [ 6 new SamplePackage(ctx), 7+ new GeometryTransitionViewPackage(ctx) 8 ]; 9}
方法二:
直接链接源码
如需使用直接链接源码,请参考直接链接源码说明
说明: "Platform"列表示支持的平台,All表示支持所有平台。
GeometryView
Name | Description | Type | Platform |
---|---|---|---|
geometryViewID | 共享元素ID. | string | OpenHarmony |
onGeometryViewClick | 点击GeometryView回调. | callback | OpenHarmony |
GeometryTransitionView
Name | Description | Type | Platform |
---|---|---|---|
geometryViewID | 用于设置绑定关系,id置空字符串清除绑定关系避免参与共享行为,id可更换重新建立绑定关系。同一个id只能有两个组件绑定且是in/out不同类型角色,不能多个组件绑定同一个id。 | string | OpenHarmony |
isFollow | 组件内共享元素转场动画参数。true代表跟随做共享动画,false代表不跟随做共享动画,默认值:false。 | boolean? | OpenHarmony |
duration | 动画执行时间,默认值:1000ms。 | number? | OpenHarmony |
pageType | 页面标志。 | 'current' | 'target' | OpenHarmony |
约束与限制:
1、仅限用于原生 Navigation 路由跳转场景;
2、在使用GeometryTransitionView时,如果跳转页面前需要重置geometryViewID,需使用以下方式:
1UIManager.dispatchViewManagerCommand( 2 findNodeHandle(nativeRef.current), 3 'changeGeometryTransitionID', 4 ['geometryTransitionID'], // 共享元素ID 5);
并且通过监听geometryTransitionIDChanged事件进行页面跳转,避免target页面先触发build导致一镜到底动效失效问题。
1DeviceEventEmitter.addListener('geometryTransitionIDChanged', () => { 2 console.log('geometryTransitionIDChanged'); 3});
No vulnerabilities found.
No security vulnerabilities found.