繁体   English   中英

PanResponder在第二次拖动时将Animated.View捕捉回原始位置

[英]PanResponder snaps Animated.View back to original position on second drag

我创建了一个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>                 

谢谢

首先,让我们来看看为什么会这样:

  • 你的onPanResponderMove回调读取手势的dy (delta Y),它给出了自手势开始以来垂直移动的像素数量。 这意味着每次开始新手势时,delta都从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上可用。

你只需要在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()      
   }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM