合并受阻
感谢提交 Pull Requests!
Thanks for submitting a pull request.


【AI-Review】【严重】【基础代码问题】【代码逻辑错误】删除 setValue 导致下一次切换动画前半段被 clamp 冻结
● 问题:本次删除了 toggleSwitchToValue 回调末尾的 switchAnimation.setValue(toValue ? -1 : 1)(base 版本 lib/index.js:152)。但 animateSwitch(lib/index.js:155-166)结束时 switchAnimation 停留在 ±this.offset(默认 width-height+1=20),该值落在 render 中 interpolatedTranslateX 的 inputRange(lib/index.js:218 value ? [-this.offset, -1] : [1, this.offset],即 [-20,-1] 或 [1,20])之外。下一次 toggleSwitchToValue 被调用时(来自 _onPanResponderRelease→toggleSwitch→toggleSwitchToValue 的手势路径,或 componentWillReceiveProps→toggleSwitchToValue 的外部 prop 变更路径),animateSwitch 会从 ±this.offset 动画到 ∓this.offset,整段动画 40 个单位中只有 19 个单位落在 inputRange 内。由于 extrapolate: 'clamp' 的作用,前 21 个单位(52.5%,约 105ms)输出被钳制为边界值,圆点保持不动;后 19 个单位(47.5%,约 95ms)才真正位移。例如开关从 true→false 时,switchAnimation 从 20→-20,但前 105ms 圆点始终停在 circlePosition(true)=-1 处,后 95ms 才从 -1 移动到 -20,用户感知到"先静止 105ms 再快速移动 95ms"的卡顿。
● 影响:严重。每次完成一次切换后,紧接着的下一次切换动画都会出现前半段冻结的视觉卡顿,与 200ms 线性动画的预期不符,用户会明显感知到开关响应延迟。base 版本依赖被删除的 setValue 将 switchAnimation 重置到 -1/1(落在新 inputRange 的边界内),下一次动画从 inputRange 内的值起步,全程线性可见,不存在该卡顿。本次修改相当于用一个更严重的动画卡顿换取了对中断场景的修复。
● 建议:保留对中断动画的 if (!finished) return 处理,但不要简单删除 setValue。可参考 0.77 分支(br_rnoh0.77,commit 5e95759)executeToggleToValue(lib/index.js:145-166)的实现思路:先 switchAnimation.stopAnimation(),再 setState,然后用 setValue(toValue ? -this.offset : this.offset) 将动画起点显式设置到新 inputRange 的边界内,最后 Animated.timing 到目标值。这样既能避免 base 版本 setValue 与 setState 时序错位导致的"跳变",又能让下一次切换的动画起点落在 inputRange 内。或在本次最小改动范围内,将 switchAnimation.setValue(toValue ? -1 : 1) 保留并移到 setState 调用之前执行,以消除时序错位而非删除该重置。


感谢提交 Pull Requests!
Thanks for submitting a pull request.


变更概述
本 PR 对鸿蒙化三方库 react-native-switch-pro 修复开关动画中断时的状态一致性问题,并更新版本号:
finished === false)时仍应用过期目标状态的问题(增加finished守卫)switchAnimation.setValue(±1)回拨,动画值行为对齐上游 1.0.5一、三方库源码修改点(重点)
1. 动画被打断时不再应用过期状态
根因:
toggleSwitchToValue中animateSwitch的完成回调不区分动画是否正常结束。动画被新的切换或手势打断(finished === false)时,回调仍执行setState更新内部value并触发用户callback,把已被打断的过期目标状态应用到 UI 和外部状态,造成内外状态不一致。修改前——回调不检查
finished,且切换完成后手动回拨动画值:toggleSwitchToValue = (result, toValue, callback = () => null) => { const { switchAnimation } = this.state this.animateHandler(this.handlerSize) if (result) { this.animateSwitch(toValue, () => { this.setState({ value: toValue, alignItems: toValue ? 'flex-end' : 'flex-start' }, () => { callback(toValue) }) switchAnimation.setValue(toValue ? -1 : 1) }) } }修改后——增加
finished守卫,去掉多余setValue:toggleSwitchToValue = (result, toValue, callback = () => null) => { this.animateHandler(this.handlerSize) if (result) { this.animateSwitch(toValue, ({ finished }) => { if (!finished) return this.setState({ value: toValue, alignItems: toValue ? 'flex-end' : 'flex-start' }, () => { callback(toValue) }) }) } }setState、不触发callback,内部状态与 UI 保持一致switchAnimation.setValue(toValue ? -1 : 1)可去掉:切换完成后动画值停在±offset,render 插值配置了extrapolate: 'clamp',视觉已位于新状态端点,无需手动回拨;行为对齐上游 1.0.5二、文档修改
三、自测说明
value:有 200ms 动画过渡,非瞬时跳变(待人工验证)资料修改
Checklist