有几个地方需要修改以使其起作用。
Step by Step:
- 您的四个圈子拥有自己的位置。因此Animated.ValueXY需要4 。
this.dataDrag = [1,2,3,4]; this.pan = this.dataDrag.map( () => new Animated.ValueXY() );
- 您
PanResponder
需要当前索引中的信息。将其拉出作为返回包含info信息的函数的函数index。
getPanResponder(index) { return PanResponder.create({ onStartShouldSetPanResponder: () => true, onPanResponderMove: Animated.event([null,{ dx: this.pan[index].x, dy: this.pan[index].y }]), onPanResponderRelease : (e, gesture) => { if(this.isDropZone(gesture)){ this.setState({ showDraggable : false }); }else{ Animated.spring( this.pan[index], {toValue:{x:0,y:0}} ).start(); } } }); }- 根据上述变化制作样式。删除不必要的外部视图以及阻塞事件。
{this.dataDrag.map((d, index) => ( <Animated.View key={index} {...this.getPanResponder(index).panHandlers} style={[styles.draggableContainer, this.pan[index].getLayout(), styles.circle]}> <Text style={styles.text}>Drag {index}</Text> </Animated.View> ))}- 做保证金技巧以减少头寸的计算。更改
top / left为marginTop / marginLeft
。
draggableContainer: { position : 'absolute', marginTop : Window.height/2 - CIRCLE_RADIUS, marginLeft : Window.width/2 - CIRCLE_RADIUS, },Final Code:
import React, { Component } from 'react';import { StyleSheet, View, Text, PanResponder, Animated, Easing, Dimensions, Platform, TouchableOpacity,} from 'react-native';let CIRCLE_RADIUS = 36;let Window = Dimensions.get('window');export class App extends Component<{}> { constructor(props){ super(props); this.dataDrag = [1,2,3,4]; this.pan = this.dataDrag.map( () => new Animated.ValueXY() ); this.state = { showDraggable : true, dropZonevalues : null, }; } getPanResponder(index) { return PanResponder.create({ onStartShouldSetPanResponder: () => true, onPanResponderMove : Animated.event([null,{ dx : this.pan[index].x, dy : this.pan[index].y }]), onPanResponderRelease: (e, gesture) => { if(this.isDropZone(gesture)){ this.setState({ showDraggable : false }); }else{ Animated.spring( this.pan[index], {toValue:{x:0,y:0}} ).start(); } } }); } isDropZone(gesture){ var dz = this.state.dropZonevalues; return gesture.moveY > dz.y && gesture.moveY < dz.y + dz.height; } setDropZonevalues(event){ this.setState({ dropZonevalues : event.nativeEvent.layout }); } render(){ return ( <View style={styles.mainContainer}> <View onLayout={this.setDropZonevalues.bind(this)} style={styles.dropZone}> <Text style={styles.text}>Drop me here!</Text> </View> {this.dataDrag.map((d, index) => ( <Animated.View key={index} {...this.getPanResponder(index).panHandlers} style={[styles.draggableContainer, this.pan[index].getLayout(), styles.circle]}> <Text style={styles.text}>Drag {index}</Text> </Animated.View> ))} </View> ); }}let styles = StyleSheet.create({ mainContainer: { flex : 1 }, dropZone : { height : 100, backgroundColor:'#2c3e50' }, text : { marginTop : 25, marginLeft : 5, marginRight : 5, textAlign : 'center', color : '#fff' }, draggableContainer: { position : 'absolute', marginTop : Window.height/2 - CIRCLE_RADIUS, marginLeft : Window.width/2 - CIRCLE_RADIUS, }, circle : { backgroundColor : '#1abc9c', width : CIRCLE_RADIUS*2, height : CIRCLE_RADIUS*2, borderRadius : CIRCLE_RADIUS },});


