Trying to make swiper with React Native PanResponder. When I click again to button after release button starts at begining position. I tried using setOffset in onPanResponderGrant but that makes button exceeds parent container when you scroll it. If sser scrolled 45% of the containers half width I'm animating button to that halfs end.
Here is a link for my code https://snack.expo.io/@sargnec/react-native-swiper
I think I made it work, with a few changes:
I kept
onPanResponderGrant: () => {
this.pan.setOffset({x: this.pan.x._value});
},handlePanResponderMove This is important so that, when a user click a second time on your button and make gestureState.dx = 10, you do read 10px, not dx since initial position (after first click)
on handlePanResponderMove, I commented "// this.setState({ xPosition: gestureState.dx })" Your "xPosition" is useful to know where was your point in the beginning, so xPosition + dx move past the limit or not. If you update it on panResponderMove, if you make many very small dx steps, you will reach DRAG_TOP_LIMIT before the end
on onPanResponderRelease: (a) Here, I changed the xPosition, and (b) I do not make a test "gesture.dx > DRAG_TOP_LIMIT", but "xPosition + gesture.dx > DRAG_TOP_LIMIT"
(optional) Actually, your xPosition is not used (and not useful) for the render, so you should remove it from the state and just make this._xPosition
So, here is the code
pan = new Animated.ValueXY();
handlePanResponderMove = (e, gestureState) => {
const currentValue = this.state.xPosition + gestureState.dx
if (currentValue > DRAG_TOP_LIMIT) {
this.pan.setValue({ x: DRAG_TOP_LIMIT })
} else if (currentValue < DRAG_ALT_LIMIT) {
this.pan.setValue({ x: DRAG_ALT_LIMIT })
} else {
this.pan.setValue({ x: gestureState.dx })
}
};
panResponder = PanResponder.create({
onMoveShouldSetPanResponder: () => true,
onPanResponderGrant: () => {
this.pan.setOffset({x: this.pan.x._value});
},
onPanResponderMove: (e, gestureState) => this.handlePanResponderMove(e, gestureState),
onPanResponderRelease: (e, gestureState) => {
this.pan.flattenOffset();
const currPosition = gestureState.dx + this.state.xPosition
if (currPosition >= DRAG_TOP_LIMIT * 0.45) {
Animated.timing(this.pan.x, {
toValue: DRAG_TOP_LIMIT,
duration: 100
}).start()
this.setState({xPosition: DRAG_TOP_LIMIT})
} else if (currPosition <= DRAG_ALT_LIMIT * 0.45) {
Animated.timing(this.pan.x, {
toValue: DRAG_ALT_LIMIT,
duration: 100
}).start()
this.setState({xPosition: DRAG_ALT_LIMIT})
} else {
this.setState({xPosition: this.state.xPosition + gestureState.dx })
}
}
})
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.