2017-02-02 9 views
0

Animated.Viewを垂直方向に移動するためのPanResponderを作成しました。私はそれを元の位置から移動するとうまくいきますが、もう一度2度移動すると元の位置にスナップしてからタッチに相対的に移動します。PanResponderは2番目のドラッグ時に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)が読み込まれます。これは、他の手は、単にスタイルプロパティtopからy値をマップ上の新しいジェスチャーを起動するたびに、デルタは0

  • AnimatedXY#getLayout()から始まることを意味します。これは、接触の開始時にyが0に設定されている場合、要素はオフセットのない最初の位置に戻ります。ジェスチャの開始時前ドラッグからのオフセット、あなたが0にこれを初期デルタをリセットする前のオフセット位置を保持するためにsetOffsetを使用し、次いでsetValueできを維持するために

は、例えば、行うことができます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.Valueで十分であるため、必ず2次元のAnimated.ValueXYを使用する必要はありません。 Valueを使用するようにコードをリファクタリングする場合は、drag.extractOffset()を呼び出してオフセットをリセットすることができます。同じことをしますが、AnimatedXYでは利用できないようです。あなただけの

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

     }, 

のように、onPanResponderGrantにオフセットしかし、また、あなたがpanResponderが解放される時に、オフセット、またはそうでなければ、いくつかの不具合がありますを平らにしてください(位置に従ってリセットされますを調整する必要が

+0

この偉大な回答で対応し、何が起こっているのかを正しく説明していただき、ありがとうございます。私はあなたが提供したものと同様の方法を使ってこの問題を最終的に解決しました。 – JmJ

1

前回のオフセットまで)を3回目または4回目にドラッグします。

onPanResponderRelease: (e, {vx, vy}) => { 
     this.state.drag.flattenOffset()  
    } 
関連する問題