React Native PanResponder限制X位置

问题描述 投票:6回答:2

我正在建立一个音乐播放器,我专注于进度条。我能够对滑动手势做出反应,但我无法限制手势的移动距离。

这就是我到目前为止所做的。我把所有东西都减少到最小:

constructor(props) {
    super(props);

    this.state = {
      pan: new Animated.ValueXY()
    };
}

componentWillMount() {
    this._panResponder = PanResponder.create({
        onMoveShouldSetResponderCapture: () => true,
        onMoveShouldSetPanResponderCapture: () => true,
        onPanResponderGrant: (e, gestureState) => {


            // Set the initial value to the current state
            let x = (this.state.pan.x._value < 0) ? 0 : this.state.pan.x._value;


            this.state.pan.setOffset({ x, y: 0 });
            this.state.pan.setValue({ x: 0, y: 0 });


        },
        onPanResponderMove: Animated.event([
            null, { dx: this.state.pan.x, dy: 0 },
        ]),
        onPanResponderRelease: (e, { vx, vy }) => {
            this.state.pan.flattenOffset();
        }
    });
}

render() {
    let { pan } = this.state;

    // Calculate the x and y transform from the pan value
    let [translateX, translateY] = [pan.x, pan.y];
    // Calculate the transform property and set it as a value for our style which we add below to the Animated.View component
    let imageStyle = { transform: [{ translateX }, { translateY }] };

    return (
        <View style={styles.container}>
            <Animated.View style={{imageStyle}} {...this._panResponder.panHandlers} />
        </View>
    );
}

这里有一个图像显示问题所在。

初始位置:

Initial position

错误的位置,超出限制:

Wrong position

因此,一旦达到极限(左侧和右侧),该想法就是停止保持运动。我试过检查是否_value < 0,但它没有工作,因为它似乎是一个偏移,而不是一个位置。

那么任何帮助将不胜感激。

android react-native gestures
2个回答
2
投票
onPanResponderMove: (e, gestureState)=> {
    this.state.pan.x._value > 0 ? null : Animated.event([
            null, 
            {dx: this.state.pan.x, dy: this.state.pan.y},
        ])(e, gestureState)
    },

1
投票

我试图做类似的事情;我想拥有它,以便您可以将页面部分拉出然后释放,然后它会回到原来的位置。

我的解决方案是:

panResponder = PanResponder.create({
  onMoveShouldSetPanResponderCapture: (e, { dx }) => {
    // This will make it so the gesture is ignored if it's only short (like a tap).
    // You could also use moveX to restrict the gesture to the sides of the screen.
    // Something like: moveX <= 50 || moveX >= screenWidth - 50
    // (See https://facebook.github.io/react-native/docs/panresponder)
    return Math.abs(dx) > 20;
  },
  onPanResponderMove: (e, gestureState) => (
    // Here, 30 is the limit it stops at. This works in both directions
    Math.abs(gestureState.dx) > 30
      ? null
      : Animated.event([null, { dx: this.animatedVal }])(e, gestureState)
  ),
  onPanResponderRelease: (e, { vx, dx }) => {
    // Here, abs(vx) is the current speed (not velocity) of the gesture,
    // and abs(dx) is the distance traveled (not displacement)
    if (Math.abs(vx) >= 0.5 || Math.abs(dx) >= 30) {
      doSomeAction();
    }
    Animated.spring(this.animatedVal, {
      toValue: 0,
      bounciness: 10,
    }).start();
  },
});
© www.soinside.com 2019 - 2024. All rights reserved.