@react-native-ohos/react-native-drax
v1.0.0
Published
A drag-and-drop system for React Native
Readme
文档模板:v0.4.2
本项目基于 react-native-drax 开发。
该第三方库的仓库已迁移至 Gitcode,且支持直接从 npm 下载,新的包名为:@react-native-ohos/react-native-drax,版本所属关系如下:
| 三方库名称 | 三方库版本(npm地址) | 发布信息 | 支持RN版本 | Autolink | 编译API版本 | 社区基线版本 | 源码地址 | | ------------ | ------------ | ------------------------------ | ------------- | ------------- |------------------------ | ------------- | ------------- | | @react-native-ohos/react-native-drax | ~ 1.0.0 | Gitcode Releases | 0.82.* | 否 | API12+ | 1.1.0 | br_rnoh0.82 | | @react-native-ohos/react-native-drax | ~ 0.12.0 | Gitcode Releases | 0.77.* | 否 | API12+ | 0.12.0 | br_rnoh0.77 | | @react-native-ohos/react-native-drax | ~ 0.10.4 | Gitcode Releases | 0.72.* | 否 | API12+ | 0.10.4 | br_rnoh0.72 | | @react-native-oh-tpl/react-native-drax | <= 0.10.3-0.0.1@deprecated | Github Releases(deprecated) | 0.72.* | 否 | API12+ | 0.10.3 | sig |
简介
react-native-drax 是一个 React Native 的拖拽库,提供跨平台的拖拽功能支持。 它提供了 DraxProvider、DraxView、DraxList、DraxScrollView 等组件,支持拖拽检测、拖拽样式、拖拽传递数据、列表项重新排序等功能。
下载安装
进入到工程目录并输入以下命令:
npm
npm install @react-native-ohos/react-native-draxyarn
yarn add @react-native-ohos/react-native-draxLink
本库实现依赖 react-native-reanimated、react-native-gesture-handler的原生端代码,如已在鸿蒙工程中引入过该库,则无需再次引入,可跳过本章节步骤,直接使用。
请参照以下文档进行引入:react-native-reanimated 文档、react-native-gesture-handler 文档。
约束与限制
兼容性
本文档内容基于以下版本验证通过:
- RNOH: 0.82.1; SDK: HarmonyOS 6.0.1 Release SDK; IDE: DevEco Studio 6.0.1 Release; ROM: 6.0.0.120 SP7;
权限要求
本库为纯 JS 库,无需申请额外权限。
使用示例
下面的代码展示了这个库的基本使用场景:
[!WARNING] 使用时 import 的库名不变。
import React, { useState } from 'react';
import { View, StyleSheet } from 'react-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { DraxProvider, DraxView } from 'react-native-drax';
export const GestureHandleExample = () => {
return (
<DraxProvider>
<GestureHandlerRootView>
<View style={styles.container}>
<DraxView
style={styles.draggable}
onDragStart={() => {
console.log('start drag');
}}
payload="world"
/>
<DraxView
style={styles.receiver}
onReceiveDragEnter={({ dragged: { payload } }) => {
console.log(`hello ${payload}`);
}}
onReceiveDragExit={({ dragged: { payload } }) => {
console.log(`goodbye ${payload}`);
}}
onReceiveDragDrop={({ dragged: { payload } }) => {
console.log(`received ${payload}`);
}}
/>
</View>
</GestureHandlerRootView>
</DraxProvider>
);
};
const styles = StyleSheet.create({
box: {
width: 100,
height: 100,
backgroundColor: 'blue',
marginTop: 100,
marginLeft: 100
},
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
width: '100%',
height: 800,
paddingTop: 500
},
draggable: {
width: 100,
height: 100,
backgroundColor: 'blue',
},
receiver: {
width: 100,
height: 100,
backgroundColor: 'green',
},
});使用说明
DraxView 拖拽基础
<DraxView
style={styles.draggable}
payload="hello"
onDragStart={() => console.log('drag start')}
onDragEnd={() => console.log('drag end')}
/>DraxList 列表排序
const [data, setData] = useState([
{ id: '1', text: 'Task 1' },
{ id: '2', text: 'Task 2' },
]);
<DraxList
data={data}
keyExtractor={(item) => item.id}
renderItem={({ item }) => <Text>{item.text}</Text>}
onReorder={({ data: newData }) => setData(newData)}
/>DraxScrollView 滚动拖拽
<DraxScrollView style={{ height: 400 }}>
<DraxView style={styles.item} payload="item1" />
<DraxView style={styles.item} payload="item2" />
</DraxScrollView>接口说明
[!TIP] "Platform"列表示该属性在原三方库上支持的平台。
[!TIP] "OpenHarmony Support"列为 yes 表示 OpenHarmony平台支持 该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。
组件
| 名称 | 参数类型 | 必填 | 平台 | OpenHarmony平台支持| 描述 | |------------|------------|----------------------|------|-----|----------------| | DraxProvider | DraxProviderProps | yes | all | yes | 拖拽上下文提供者组件,必须包裹所有 Drax 组件 | | DraxView | DraxViewProps | no | all | yes | 可拖拽视图组件 | | DraxHandle | DraxHandleProps | no | all | yes | 拖拽手柄组件,配合 DraxView 的 dragHandle 属性使用 | | DraxList | DraxListProps | no | all | yes | 支持拖拽排序的列表组件,可适配 FlatList、FlashList 等任意列表组件 | | DraxScrollView | DraxScrollViewProps | no | all | yes | 支持拖拽和自动滚动的滚动视图组件 |
属性
DraxProvider
| Name | Description | Type | Required | Platform | OpenHarmony Support | | :-------------------------------: | :----------------------------------------------------------: | :-----------: | :------: | :---------: | :---------------: | | style | 容器样式 | object | no | iOS/Android | Yes | | debug | 是否开启调试模式 | boolean | no | iOS/Android | Yes | | onDragStart | 任意拖拽开始时的回调函数 | function | no | iOS/Android | Yes | | onDrag | 任意拖拽进行中的回调函数 | function | no | iOS/Android | Yes | | onDragEnd | 任意拖拽结束时的回调函数 | function | no | iOS/Android | Yes | | children | 子组件 | React Element | no | iOS/Android | Yes |
DraxView
| Name | Description | Type | Required | Platform | OpenHarmony Support | | :-------------------------------: | :----------------------------------------------------------: | :-----------: | :------: | :---------: | :---------------: | | onDragStart | 拖拽开始时的回调函数 | function | no | iOS/Android | Yes | | onDrag | 拖拽过程中的回调函数 | function | no | iOS/Android | Yes | | onDragEnter | 拖拽进入接收方时的回调函数 | function | no | iOS/Android | Yes | | onDragOver | 在接收方上方拖拽时的回调函数 | function | no | iOS/Android | Yes | | onDragExit | 拖拽离开接收方时的回调函数 | function | no | iOS/Android | Yes | | onDragEnd | 拖拽结束时(未在接收方上方)的回调函数 | function | no | iOS/Android | Yes | | onDragDrop | 拖拽在接收方上方释放时的回调函数 | function | no | iOS/Android | Yes | | onSnapEnd | 拖拽释放回弹动画结束时的回调函数 | function | no | iOS/Android | Yes | | onReceiveDragEnter | 有拖拽项进入时的回调函数 | function | no | iOS/Android | Yes | | onReceiveDragOver | 有拖拽项在上方悬停时的回调函数 | function | no | iOS/Android | Yes | | onReceiveDragExit | 有拖拽项离开时的回调函数 | function | no | iOS/Android | Yes | | onReceiveDragDrop | 有拖拽项在上方释放时的回调函数 | function | no | iOS/Android | Yes | | onReceiveSnapEnd | 接收方回弹动画结束时的回调函数 | function | no | iOS/Android | Yes | | onMonitorDragStart | 监测到拖拽开始时的回调函数 | function | no | iOS/Android | Yes | | onMonitorDragEnter | 监测到拖拽进入时的回调函数 | function | no | iOS/Android | Yes | | onMonitorDragOver | 监测到拖拽进行时的回调函数 | function | no | iOS/Android | Yes | | onMonitorDragExit | 监测到拖拽离开时的回调函数 | function | no | iOS/Android | Yes | | onMonitorDragEnd | 监测到拖拽结束时的回调函数 | function | no | iOS/Android | Yes | | onMonitorDragDrop | 监测到拖拽释放时的回调函数 | function | no | iOS/Android | Yes | | animateSnap | 是否在拖拽释放后为悬停视图快照添加回弹动画 | boolean | no | iOS/Android | Yes | | snapDelay | 拖拽释放后回弹动画开始前的延迟(毫秒) | number | no | iOS/Android | Yes | | snapDuration | 回弹动画持续时间(毫秒) | number | no | iOS/Android | Yes | | snapAnimator | 自定义回弹动画函数 | function | no | iOS/Android | Yes | | payload | 拖拽时传递的数据 | any | no | iOS/Android | Yes | | dragPayload | 拖拽方传输的数据 | any | no | iOS/Android | Yes | | receiverPayload | 接收方传输的数据 | any | no | iOS/Android | Yes | | dragInactiveStyle | 拖拽前拖拽方的样式 | object | no | iOS/Android | Yes | | draggingStyle | 拖拽过程中应用于拖拽方的样式 | object | no | iOS/Android | Yes | | draggingWithReceiverStyle | 当拖拽方直接在接收方上方时应用于拖拽方的样式 | object | no | iOS/Android | Yes | | draggingWithoutReceiverStyle | 当拖拽方不在接收方上方时应用于拖拽方的样式 | object | no | iOS/Android | Yes | | dragReleasedStyle | 当拖拽方释放时应用于拖拽方的样式 | object | no | iOS/Android | Yes | | hoverStyle | 当快照悬停时应用于拖拽方快照的样式 | object | no | iOS/Android | Yes | | hoverDraggingStyle | 拖拽时应用于拖拽方快照的样式 | object | no | iOS/Android | Yes | | hoverDraggingWithReceiverStyle | 当拖拽方直接在接收方上方时应用于拖拽方快照的样式 | object | no | iOS/Android | Yes | | hoverDraggingWithoutReceiverStyle | 当拖拽方不在接收方上方时应用于拖拽方快照的样式 | object | no | iOS/Android | Yes | | hoverDragReleasedStyle | 当拖拽停止时应用于拖拽方快照的样式 | object | no | iOS/Android | Yes | | receiverInactiveStyle | 拖拽开始前应用于接收方的样式 | object | no | iOS/Android | Yes | | receivingStyle | 当拖拽直接在接收方上方时应用于接收方的样式 | object | no | iOS/Android | Yes | | otherDraggingStyle | 其他拖拽方拖拽期间应用于拖拽方的样式 | object | no | iOS/Android | Yes | | otherDraggingWithReceiverStyle | 当其他拖拽方直接在接收方上方时应用于拖拽方的样式 | object | no | iOS/Android | Yes | | otherDraggingWithoutReceiverStyle | 当其他拖拽方不在接收方上方时应用于拖拽方的样式 | object | no | iOS/Android | Yes | | renderContent | 渲染拖拽组件内部子节点的内容 | function | no | iOS/Android | Yes | | renderHoverContent | 用于渲染拖拽复制组件内部子节点的内容 | function | no | iOS/Android | Yes | | registration | 回调函数,可接收组件内部传输的数据 | function | no | iOS/Android | Yes | | onMeasure | 回调函数,可接收组件内部传输的数据 | function | no | iOS/Android | Yes | | lockDragXPosition | 指示是否在水平方向(x轴)锁定拖拽 | boolean | no | iOS/Android | Yes | | lockDragYPosition | 指示是否在垂直方向(y轴)锁定拖拽 | boolean | no | iOS/Android | Yes | | children | 渲染拖拽组件内部子节点的内容。仅当 renderContent 渲染方法不存在时此参数有效 | React Element | no | iOS/Android | Yes | | noHover | 设置是否禁用拖拽复制功能 | boolean | no | iOS/Android | Yes | | longPressDelay | 设置视图识别触摸和长按手势的最短时间(以毫秒为单位) | number | no | iOS/Android | Yes | | draggable | 指示是否允许拖拽。默认值为 true | boolean | no | iOS/Android | Yes | | receptive | 指示是否可接收拖拽 | boolean | no | iOS/Android | Yes | | monitoring | 指示是否可监测拖拽 | boolean | no | iOS/Android | Yes | | rejectOwnChildren | 如果为 true,则不接收来自自身子级的拖拽 | boolean | no | iOS/Android | Yes | | collisionAlgorithm | 碰撞检测算法:'center'(默认)、'intersect' 或 'contain' | string | no | iOS/Android | Yes | | dragBoundsRef | 限制拖拽范围的 View 引用 | RefObject | no | iOS/Android | Yes | | dragActivationFailOffset | 长按等待期间手指漂移超过此值(px)则取消拖拽。需配合 longPressDelay 使用。受系统触摸容差约束,仅在设值小于系统容差时生效。 | number | no | iOS/Android | Yes | | scrollHorizontal | 提示该视图位于水平滚动容器内 | boolean | no | Web | Yes | | dynamicReceptiveCallback | 动态决定是否可接收拖拽的回调函数 | function | no | iOS/Android | Yes | | acceptsDrag | 基于 payload 的条件接收判断函数 | function | no | iOS/Android | Yes | | capacity | 最大可接收的拖拽项数量 | number | no | iOS/Android | Yes | | dragHandle | 如果为 true,拖拽仅通过 DraxHandle 子组件激活 | boolean | no | iOS/Android | Yes | | isParent | 如果为 true,将此视图视为可嵌套子 DraxView 的父视图 | boolean | no | iOS/Android | Yes |
DraxHandle
| Name | Description | Type | Required | Platform | OpenHarmony Support | | :------: | :---------------------------: | :-----------: | :------: | :---------: | :---------------: | | children | 手柄内部子节点 | React Element | yes | iOS/Android | Yes | | style | 手柄容器样式 | object | no | iOS/Android | Yes |
DraxScrollView
| Name | Description | Type | Required | Platform | OpenHarmony Support | | :------: | :---------------------------: | :-----------: | :------: | :---------: | :---------------: | | children | 组件子节点 | React Element | no | iOS/Android | Yes | | onScroll | 滑动事件回调函数 | function | no | iOS/Android | Yes | | autoScrollIntervalLength | 自动滚动间隔长度 | number | no | iOS/Android | Yes | | autoScrollJumpRatio | 自动滚动跳跃比例 | number | no | iOS/Android | Yes | | autoScrollBackThreshold | 向后自动滚动的拖拽位置阈值 | number | no | iOS/Android | Yes | | autoScrollForwardThreshold | 向前自动滚动的拖拽位置阈值 | number | no | iOS/Android | Yes |
DraxList
| Name | Description | Type | Required | Platform | OpenHarmony Support | | :--------------------------------------------: | :----------------------------------------------------------: | :------: | :------: | :---------: | :---------------: | | data | DraxList 组件的数据源 | array | yes | iOS/Android | Yes | | keyExtractor | 用于从项目中提取唯一键的函数 | function | yes | iOS/Android | Yes | | onReorder | 列表项重新排序时的回调处理程序 | function | yes | iOS/Android | Yes | | renderItem | 渲染每个列表项的函数,接收 FlatList 标准的 renderItem 参数(ListRenderItemInfo) | function | yes | iOS/Android | Yes | | component | 要渲染的列表组件,默认使用 FlatList。可传入 FlashList、LegendList 等 | ComponentType | no | iOS/Android | Yes | | ref | 转发到底层列表组件的 Ref | Ref | no | iOS/Android | Yes | | id | 可选的容器 DraxView id | string | no | iOS/Android | Yes | | reorderStrategy | 重排序策略:'insert'(默认)或 'swap' | string | no | iOS/Android | Yes | | longPressDelay | 拖拽开始前的长按时间(毫秒),默认 250 | number | no | iOS/Android | Yes | | lockToMainAxis | 如果为 true,将项目拖拽锁定到列表的主轴 | boolean | no | iOS/Android | Yes | | animationConfig | 项目位移动画配置:预设名称或自定义配置对象 | string | object | no | iOS/Android | Yes | | inactiveItemStyle | 拖拽进行中应用于非拖拽项的样式 | object | no | iOS/Android | Yes | | itemEntering | 项目进入列表时的 Reanimated 布局动画 | EntryOrExitLayoutType | no | iOS/Android | Yes | | itemExiting | 项目离开列表时的 Reanimated 布局动画 | EntryOrExitLayoutType | no | iOS/Android | Yes | | itemDraxViewProps | 应用于每个列表项的 DraxView 属性 | object | no | iOS/Android | Yes | | containerDraxViewProps | 应用于容器的 DraxView 属性 | object | no | iOS/Android | Yes | | containerStyle | 容器样式 | object | no | iOS/Android | Yes | | style | 列表组件样式 | object | no | iOS/Android | Yes | | horizontal | 列表是否水平布局,默认 false | boolean | no | iOS/Android | Yes | | numColumns | 列数(网格布局),默认 1 | number | no | iOS/Android | Yes | | onDragStart | 列表项拖拽开始回调 | function | no | iOS/Android | Yes | | onDragPositionChange | 列表项拖拽位置变化回调 | function | no | iOS/Android | Yes | | onDragEnd | 列表项拖拽结束回调 | function | no | iOS/Android | Yes |
遗留问题
- [ ] DraxList和DraxScrollView组件存在拖拽不流畅的情况,issue#1
- [ ] DraxView的otherDraggingWithReceiverStyle属性不生效,issue#13
- [ ] DraxView的otherDraggingWithoutReceiverStyle属性不生效,issue#14
- [ ] DraxList的itemExiting属性不生效,issue#15
其他
无
目录结构
/rntpc_react-native-drax # 项目根目录
├── src # RN源码
│ ├── compat # 兼容层(react-native-gesture-handler 版本差异适配)
│ │ ├── index.ts
│ │ ├── detectVersion.ts
│ │ ├── types.ts
│ │ └── useDraxPanGesture.ts
│ ├── hooks # 自定义 Hooks
│ │ ├── index.ts
│ │ ├── useCallbackDispatch.tsx
│ │ ├── useDragGesture.ts
│ │ ├── useDraxContext.ts
│ │ ├── useDraxId.ts
│ │ ├── useDraxMethods.ts
│ │ ├── useDraxScrollHandler.ts
│ │ ├── useSortableBoard.ts
│ │ ├── useSortableList.ts
│ │ ├── useSpatialIndex.ts
│ │ ├── useViewStyles.ts
│ │ └── useWebScrollFreeze.ts
│ ├── index.ts # 入口文件(对外导出)
│ ├── Drax.ts # Drax 命名空间对象
│ ├── DraxContext.ts # Drax 上下文
│ ├── DraxHandle.tsx # DraxHandle 组件
│ ├── DraxHandleContext.ts
│ ├── DraxList.tsx # DraxList 组件
│ ├── DraxProvider.tsx # DraxProvider 组件
│ ├── DraxScrollView.tsx # DraxScrollView 组件
│ ├── DraxSubprovider.tsx
│ ├── DraxView.tsx # DraxView 组件
│ ├── HoverLayer.tsx # 拖拽悬停层
│ ├── DebugOverlay.tsx # 调试浮层
│ ├── SortableBoardContainer.tsx # SortableBoardContainer 组件
│ ├── SortableBoardContext.ts
│ ├── SortableContainer.tsx # SortableContainer 组件
│ ├── SortableItem.tsx # SortableItem 组件
│ ├── SortableItemContext.ts # SortableItem 上下文
│ ├── math.ts # 数学工具(snapToAlignment、packGrid 等)
│ ├── params.ts # 默认参数配置
│ └── types.ts # 类型定义
├── lib # 构建产物
├── example # 示例项目
├── docs # 文档
├── README.md # 中文安装使用方法
├── README_en.md # 英文安装使用方法贡献代码
使用过程中发现任何问题都可以提交 Issue,当然,也非常欢迎提交 PR 。
开源协议
本项目基于 The MIT License(MIT),请自由地享受和参与开源。
