2017-02-02 110 views
0

我已创建PanResponder以垂直移动Animated.View。当我从原始位置移动它时,它可以正常工作,但是一旦我再次移动它,它就会回到其原始位置,然后相对于触摸移动。PanResponder在第二次拖动时将Animated.View捕捉回原始位置

我正在将响应者直接打开到Animated.View,这是否会造成这种行为?

这是我如何定义我PanResponder:

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

this._responder = PanResponder.create({            
    onStartShouldSetPanResponder:() => true,        
    onPanResponderMove: Animated.event([null, {       
     dy: this.state.drag.y            
    }]),                 
    onPanResponderRelease: (e, coords) => { 
     ... 
    }  
}) 

和应用响应我的Animated.View

<Animated.View {...this._responder.panHandlers} style={this.state.drag.getLayout()}> 
    // children go here 
</Animated.View>     

感谢

回答

3

首先,让我们来看看为什么发生这种情况:

  • 您的onPanResponderMove回调会读取手势的dy(增量Y),它会为您提供从手势开始后垂直移动的像素数量。这意味着每次启动新手势时,增量从0开始。

  • AnimatedXY#getLayout()另一方面只将y值映射到样式属性top。这意味着当触摸开始时y设置为0时,元素将会弹回到其初始非偏移位置。

为了保存来自先前拖动的偏移,则可以使用setOffset保留以前偏移位置,然后setValue初始增量重置为0。这是可以做到的手势开始时,例如在onPanResponderGrant

this._responder = PanResponder.create({ 
    onStartShouldSetPanResponder:() => true, 
    onPanResponderGrant: (evt, gestureState) => { 
    this.state.drag.setOffset(this.state.drag.__getValue()); 
    this.state.drag.setValue({ x: 0, y: 0 }); 
    }, 
    onPanResponderMove: Animated.event([ 
    null, 
    { dy: this.state. drag.y } 
    ]) 
}); 

正如你所看到的,我们使用的是“私人”的方法__getValue()这里。通常,不建议同步读取Animated.value的值,因为动画可能会被卸载到本机线程,并且该值可能不是最新的。在这里,在手势开始时,它应该是安全的。作为一个侧面说明,由于您只是将元素移动到Y轴上,因此您不一定需要使用二维Animated.ValueXY,因为基本的Animated.Value就足够了。如果您重构代码以使用Value,则可以致电drag.extractOffset()来重置偏移量。它做同样的事情,但似乎不可用于AnimatedXY

+0

谢谢您花时间回复这个好的答案,并正确解释发生了什么。我最终使用与您提供的方法相似的方法设法解决了这个问题。 – JmJ

1

你只需要调整onPanResponderGrant偏移,像

onPanResponderGrant: (e, gestureState) => { 
      this.state.drag.setOffset({x: this.state.drag.x._value, y: this.state.drag.y._value}); 
      this.state.drag.setValue({x: 0, y: 0}) 

     }, 

而且还确保您拼合抵消panResponder被释放时,否则就会有一些毛刺(该位置将根据重置当您拖拽第3次或第4次时,上一次偏移)。

onPanResponderRelease: (e, {vx, vy}) => { 
     this.state.drag.flattenOffset()  
    } 
相关问题