拖拽排序组件,支持列表拖拽排序
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
fix:AnySizeDragSortableView和AutoDragSortableView首次不能拖动item到底部,滚动条不能自动滚动,version:2.5.1-beta.3 Signed-off-by: ding_chengjie <ding_chengjie@hoperun.com> | 19 天前 | |
add img | 5 年前 | |
!7 merge br_rnoh0.77 into br_rnoh0.77 fix:AnySizeDragSortableView和AutoDragSortableView首次不能拖动item到底部,滚动条不能自动滚动,version:2.5.1-beta.3 Created-by: weixin_43325221 Commit-by: ding_chengjie Merged-by: openharmony_ci Description: >[fix:AnySizeDragSortableView和AutoDragSortableView首次不能拖动item到底部,滚动条不能自动滚动,version:2.5.1-beta.3](https://gitcode.com/CPF-RN/react-native-drag-sort/issues/3) ## 变更概述 本PR 对鸿蒙化三方库进行质量加固代码同步>[#3](https://gitcode.com/CPF-RN/react-native-drag-sort/issues/3) 代码相关修改: - 新增 curScrollData 种子数据初始化(ensureScrollData + onLayout) - dealtScrollStatus 边界状态改为方向感知覆盖 - scrollTo 新增 hasScroll 看门狗定时器 - 向上自动滚动触发条件新增 offsetY > 0 守卫 - 拖动边界夹紧(clamp)条件改为按滚动状态判断(仅 AutoDragSortableView) - isDragFreely 属性真正生效(仅 AutoDragSortableView) ## 一、三方库代码修改点 **1. 新增 curScrollData 种子数据初始化(ensureScrollData + onLayout)** **根因**:根因:curScrollData 仅由 ScrollView 的 onScroll 回调初始化,用户从未滚动过列表时 onScroll 不会触发,首次拖动时 curScrollData 为 null,isStartupAuto() 返回 false,自动滚动触发分支被整体跳过 **修改前** ----curScrollData 仅在 onScroll 中赋值,首次拖动时为 null,无法自动滚动 ts onScrollListener = (event) => { const nativeEvent = event.nativeEvent this.curScrollData = { totalHeight: nativeEvent.contentSize.height, windowHeight: nativeEvent.layoutMeasurement.height, offsetY: nativeEvent.contentOffset.y, hasScroll: true, } if (nativeEvent.contentOffset.y !== 0) this.isHasMeasure = true; if (this.props.onScrollListener) this.props.onScrollListener(event) } **修改后**------新增 ensureScrollData 在 onLayout(布局完成,无需滚动)时播种种子数据,拖动开始时兜底再调一次;滚动发生后真实 onScroll 数据自动覆盖种子 ts // 确保curScrollData已初始化,以便首次拖动时自动滚动功能生效 ensureScrollData = (windowHeight) => { if (!this.curScrollData && windowHeight > 0) { this.curScrollData = { totalHeight: Number.MAX_SAFE_INTEGER, windowHeight: windowHeight, offsetY: 0, hasScroll: true, }; } }; onScrollViewLayout = (event) => { const { height } = event.nativeEvent.layout; this.scrollViewHeight = height; this.ensureScrollData(height); }; // render 中 ScrollView 新增挂载 onLayout={this.onScrollViewLayout} // 拖动开始(startTouch)中兜底 this.ensureScrollData(this.scrollViewHeight || 0); **2.dealtScrollStatus 边界状态改为方向感知覆盖** 根因:边界状态无条件覆盖 forceScrollStatus,首次拖动时种子数据 offsetY=0 处于顶部边界,向下自动滚动启动后第一个周期即被覆盖为 2(ONLY_DOWN),interval 自杀 **修改前** —— 边界状态无条件覆盖,正在进行的自动滚动被掐灭 ts if (totalHeight <= windowHeight + offsetY) { this.autoObj.forceScrollStatus = -2; } else if (offsetY <= 0) { this.autoObj.forceScrollStatus = 2; } **修改后** —— 仅在与当前滚动方向冲突时才覆盖,保证进行中的自动滚动不被边界状态终止 ts if (totalHeight <= windowHeight + offsetY) { // At the bottom — stop downward auto-scroll unless we're already scrolling up. if (this.autoObj.forceScrollStatus !== -1) { this.autoObj.forceScrollStatus = -2; } } else if (offsetY <= 0) { // At the top — stop upward auto-scroll unless we're already scrolling down. if (this.autoObj.forceScrollStatus !== 1) { this.autoObj.forceScrollStatus = 2; } } **3. scrollTo 新增 hasScroll 看门狗定时器** **根因:** hasScroll 置 false 后依赖下一次 onScroll 事件置回 true,平台未回调 onScroll 时 hasScroll 永远为 false,自动滚动 interval 每个 tick 直接 return,静默停摆 **修改前** -----hasScroll 置 false 后只能等待 onScroll 恢复,无恢复手段 //Barrel effect, the slowest is 1.x1 this.curScrollData.hasScroll = false; this.scrollRef && this.scrollRef.scrollTo({x: 0, y: height, animated}); **修改后**------每次 scrollTo 重置看门狗定时器,超过 3 个滚动周期强制恢复 hasScroll;clearAutoInterval 中同步清理定时器防泄漏 //Barrel effect, the slowest is 1.x1 this.curScrollData.hasScroll = false; if (this._hasScrollTimer) { clearTimeout(this._hasScrollTimer); } this._hasScrollTimer = setTimeout(() => { if (this.curScrollData && !this.curScrollData.hasScroll) { this.curScrollData.hasScroll = true; } }, this.props.autoThrottleDuration * 3) this.scrollRef && this.scrollRef.scrollTo({x: 0, y: height, animated}); **4. 向上自动滚动触发条件新增 offsetY > 0 守卫** **根因**:页处于顶部(offsetY=0)时触发上滚是无效空转,scrollTo 顶部修正分支直接 return;且种子数据 offsetY=0 时不应触发上滚 **修改前** ----仅判断速度和位移,顶部也可触发上滚 ts } else if ((tempStatus === 0 || tempStatus === -2) && -vy > 0.01 && maxUpDiss < 0) { **修改后**------仅当页面已实际向下滚动过(offsetY > 0)才触发上滚 ts } else if ((tempStatus === 0 || tempStatus === -2) && -vy > 0.01 && this.curScrollData.offsetY > 0 && maxUpDiss < 0) { **5. 拖动边界夹紧(clamp)条件改为按滚动状态判断(仅 AutoDragSortableView)** **根因**:修改点1落地后 isStartupAuto() 恒为 true,旧条件导致边界夹紧永久失效,手动拖动可将 item 拖出内容边界;且自动滚动进行中执行夹紧会与列表滚动冲突,item 被冻在边界无法跟随移动 **修改前** ----仅在无滚动数据时夹紧 ts if (!this.isStartupAuto()) { if (this.touchCurItem.originTop + dy < 0) { dy = -this.touchCurItem.originTop } else if (this.touchCurItem.originTop + dy > maxHeight) { dy = maxHeight - this.touchCurItem.originTop } } **修改后**------非自动滚动进行中(forceScrollStatus 非 ±1)即夹紧,自动滚动中放开夹紧让 item 跟随列表移动 ts if (this.autoObj.forceScrollStatus !== 1 && this.autoObj.forceScrollStatus !== -1) { if (this.touchCurItem.originTop + dy < 0) { dy = -this.touchCurItem.originTop } else if (this.touchCurItem.originTop + dy > maxHeight) { dy = maxHeight - this.touchCurItem.originTop } } **6. isDragFreely 属性真正生效(仅 AutoDragSortableView)** **根因**:isDragFreely(自由拖动)属性已声明但未拦截自动滚动触发逻辑 **修改前** -----自动滚动触发不受 isDragFreely 控制 ts if (this.isStartupAuto()) { **修改后**------isDragFreely 为 true 时跳过自动滚动触发 ts if (this.isStartupAuto() && !this.props.isDragFreely) { ## 二、example测试用例 无新增  ## 三、文档修改 - CHANGELOG.md:新增 2.5.1-beta.3版本记录 ## 四、自测说明 - 使用原有用例 ## 资料修改 - 是否已在 README 和 package.json 修改了版本信息:是(版本号 2.5.0-> 2.5.1-beta.3,涉及 package.json / example/package.json / CHANGELOG.md) Checklist ## Checklist - [x] 已关联 Issue(#3) - [x] 根因分析和方案说明已补全(见"一、三方库源码修改点"每项的根因 + 修改前/修改后对比及 example 验证) - [x] 修复代码与测试用例同步提交(原有用例) - [x] 已列出触发的用例及运行结果(见"四、自测说明") - [x] 已通过 AI 扫描评审 - [x] 所有测试用例通过(人工验证:使用原有用例) - [x] 兼容性影响和依赖关系影响已完成分析(本次为bug修改,无 API 变更,不涉及依赖关系变化;修改均为内部实现,不影响对外接口) See merge request: CPF-RN/react-native-drag-sort!7 | 18 天前 | |
fix:AnySizeDragSortableView和AutoDragSortableView首次不能拖动item到底部,滚动条不能自动滚动,version:2.5.1-beta.3 Signed-off-by: ding_chengjie <ding_chengjie@hoperun.com> | 19 天前 | |
Initial commit | 8 年前 | |
chore:补充example工程 Signed-off-by: tangshutong <tangshutong3@h-partners.com> | 2 个月前 | |
syntax highlight | 5 年前 | |
syntax highlight | 5 年前 | |
chore:补充example工程 Signed-off-by: tangshutong <tangshutong3@h-partners.com> | 2 个月前 |
@react-native-ohos/react-native-drag-sort
This project is based on react-native-drag-sort
Documentation
License
This library is licensed under The Apache-2.0 License (Apache-2.0)