在这里你可以看到GIF中的所有视图。 View1,View 2和View 3.所有都是拖动。我想只查看3是可拖动的,其他拖动完成拖3后。
1。拖动3 - 首先拖动。
2。拖动2 - 第二次拖动。
第3。拖动1 - 第三次拖动。
代码:
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');
const instructions = Platform.select({
ios: 'Press Cmd+R to reload,\n' +
'Cmd+D or shake for dev menu',
android: 'Double tap R on your keyboard to reload,\n' +
'Shake or press menu button for dev menu',
});
export default class App extends Component<{}> {
constructor(props){
super(props);
this.state = {
showDraggable : true,
dropZoneValues : null,
pan : new Animated.ValueXY(),
dataDrag : [1,2,3,4],
};
this.panResponder = PanResponder.create({
onStartShouldSetPanResponder : () => true,
onPanResponderMove : Animated.event([null,{
dx : this.state.pan.x,
dy : this.state.pan.y
}]),
onPanResponderRelease : (e, gesture) => {
if(this.isDropZone(gesture)){
this.setState({
showDraggable : false
});
}else{
Animated.spring(
this.state.pan,
{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.state.dataDrag.map((d, index) => (
<View key = {index} style={styles.draggableContainer}>
<Animated.View
{...this.panResponder.panHandlers}
style={[this.state.pan.getLayout(), styles.circle]}>
<Text style={styles.text}>Drag {index}</Text>
</Animated.View>
</View>
))}
</View>
);
}
renderDraggable(){
//if(this.state.showDraggable){
return (
<View style={styles.draggableContainer}>
<Animated.View
{...this.panResponder.panHandlers}
style={[this.state.pan.getLayout(), styles.circle]}>
<Text style={styles.text}>Drag me!</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',
top : Window.height/2 - CIRCLE_RADIUS,
left : Window.width/2 - CIRCLE_RADIUS,
},
circle : {
backgroundColor : '#1abc9c',
width : CIRCLE_RADIUS*2,
height : CIRCLE_RADIUS*2,
borderRadius : CIRCLE_RADIUS
},
});
GIF:
我想低于结果:
答案 0 :(得分:6)
有几个地方需要修改以使其有效。
您的四个圈子拥有自己的位置。所以4 <{1}}是必需的。
Animated.ValueXY
您的this.dataDrag = [1,2,3,4];
this.pan = this.dataDrag.map( () => new Animated.ValueXY() );
需要当前索引中的信息。把它拉出来
返回函数的函数,包括PanResponder
的信息。
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,
},