【问题标题】:panResponder starts at begining position in every touchpanResponder 在每次触摸时从起始位置开始
【发布时间】:2020-09-28 16:36:17
【问题描述】:

尝试使用 React Native PanResponder 制作 swiper。当我在释放按钮从开始位置开始后再次单击按钮时。我尝试在 onPanResponderGrant 中使用 setOffset ,但这会使按钮在滚动时超出父容器。如果 sser 滚动了 45% 的容器一半宽度,我将动画按钮设置到该一半结束。

这是我的代码的链接 https://snack.expo.io/@sargnec/react-native-swiper

【问题讨论】:

    标签: react-native animation swiper panresponder


    【解决方案1】:

    我想我做到了,只是做了一些改动:

    1. 我坚持

      onPanResponderGrant: () => {
      this.pan.setOffset({x: this.pan.x._value});
      },handlePanResponderMove 这很重要,因此,当用户第二次单击您的按钮并使gestureState.dx = 10 时,您确实会读取10px,而不是自初始位置(第一次单击后)起的dx

    2. 在 handlePanResponderMove 上,我评论了“// this.setState({ xPosition: gestureState.dx })” 你的“xPosition”对于知道你的点在哪里开始很有用,所以 xPosition + dx 是否超过了限制.如果你在 panResponderMove 上更新它,如果你做了很多非常小的 dx 步骤,你会在结束前达到 DRAG_TOP_LIMIT

    3. onPanResponderRelease 上:(a) 在这里,我改变了 xPosition,并且 (b) 我不做测试“gesture.dx > DRAG_TOP_LIMIT”,而是“xPosition + gesture.dx > DRAG_TOP_LIMIT”

    4. (可选)实际上,您的 xPosition 并没有用于渲染(也没有用处),因此您应该将其从状态中移除并制作 this._xPosition

    所以,这里是代码

    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 })                        
            }                                                                                            
        }                                                                                                
    })
    

    【讨论】:

    • 这仍然超出限制,有时当按钮处于限制时它会返回起点并从那里动画到限制
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多