我正在尝试在React Native
中实现一个自定义的垂直滑块。为此,我使用了PanResponder
。由于滑块是垂直的,因此我仅更改了y
值。为了将对象停在滑块的边界上,我在调用Animated.event
之前检查它是否已经到达任何对象。
我的滑块工作正常,直到我快速滑动对象。然后onPanResponderMove
回调似乎很少被调用,并且对象停止在轨道之外,而不是边界。
componentWillMount() {
this.panResponder = PanResponder.create({
onStartShouldSetPanResponder: (evt, gestureState) => true,
onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
onMoveShouldSetPanResponder: (evt, gestureState) => true,
onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
onPanResponderGrant: this._handleOnPanResponderGrant.bind(this),
onPanResponderMove: this._handleOnPanResponderMove.bind(this),
onPanResponderRelease: this._handleOnPanResponderRelease.bind(this)
})
}
_handleOnPanResponderGrant() {
this.state.pan.setOffset({ x: this.state.pan.x._value, y: this.state.pan.y._value })
this.state.pan.setValue({ x: 0, y: 0 })
}
_handleOnPanResponderMove(e, gestureState) {
// some calculations - seems to be correct since everything is working fine until I swipe very fast
if (reachedBorders(...)) { // this takes into account also the direction so it won't get stuck on the border
return true
}
return Animated.event([null, { dy: this.state.pan.y }])(e, gestureState)
}
_handleOnPanResponderRelease() {
this.state.pan.flattenOffset()
}
我究竟做错了什么?我的方法是否正确(如果在滑块之外,则跳过
Animated.event
)?更新:
可能的问题是,您无法按照this GitHub issue中所述在手势期间立即停止
PanResponder
移动。 最佳答案
可以尝试让PanResponder
值的使用者改用pan.y
值,而不是尝试阻止pan
更新interpolated
值。例如,如果边界位于10
和250
,则可以使用以下方法:
... style={{transform: [{translateY: this.state.pan.y.interpolate({
inputRange: [10, 250],
outputRange: [10, 250],
extrapolate: 'clamp'
})}]}}
在
Release
方法中,您还需要将值限制在边界之内,但是插值将防止动画过分。