2017-02-02 97 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()  
    } 
相關問題