У меня есть круги, я должен заставить эти круги двигаться в отведенном для этого месте, и если на одном из них происходит длительное давление, то это вызывает событие.
Я сделал это, но это не такЭто, кажется, работает очень хорошо.
Я использовал Animated.View
с TouchableWithoutFeedback
внутри, который использует функцию события onLongPress
, но в некоторых случаях это работает, в другом ничего не работает.
Можете ли вы дать мне несколько советов по этому поводу?
Ссылка: перекусить
Код:
import React, { Component } from 'react';
import {
StyleSheet,
View,
Text,
PanResponder,
Animated,
TouchableWithoutFeedback,
} from 'react-native';
class Draggable extends Component {
constructor(props) {
super(props);
this.state = {
showDraggable: true,
dropAreaValues: null,
pan: new Animated.ValueXY(),
opacity: new Animated.Value(1),
};
}
componentWillMount() {
this._val = { x: 0, y: 0 };
this.state.pan.addListener(value => (this._val = value));
this.panResponder = PanResponder.create({
onStartShouldSetPanResponder: (e, gesture) => true,
onPanResponderGrant: (e, gesture) => {
this.state.pan.setOffset({
x: this._val.x,
y: this._val.y,
});
this.state.pan.setValue({ x: 0, y: 0 });
},
onPanResponderMove: Animated.event([
null,
{ dx: this.state.pan.x, dy: this.state.pan.y },
]),
onPanResponderRelease: (e, gesture) => {
if (this.isDropArea(gesture)) {
Animated.timing(this.state.opacity, {
toValue: 0,
duration: 1000,
}).start(() =>
this.setState({
showDraggable: false,
})
);
}
},
});
}
isDropArea(gesture) {
return gesture.moveY < 200;
}
render() {
return (
<View style={{ width: '20%', alignItems: 'center' }}>
{this.renderDraggable()}
</View>
);
}
renderDraggable() {
const panStyle = {
transform: this.state.pan.getTranslateTransform(),
};
if (this.state.showDraggable) {
return (
<View style={{ position: 'absolute' }}>
<Animated.View
{...this.panResponder.panHandlers}
style={[panStyle, styles.circle, { opacity: this.state.opacity }]}>
<TouchableWithoutFeedback
style={{}}
onLongPress={() => console.log('el:', this.props.id)}>
<Text style={styles.text}>{this.props.id}</Text>
</TouchableWithoutFeedback>
</Animated.View>
</View>
);
}
}
}
export default class App extends Component {
render() {
return (
<View style={styles.mainContainer}>
<View style={styles.dropZone}>
<Text style={styles.text}>Drop them here!.</Text>
</View>
<View style={styles.ballContainer} />
<View style={styles.row}>
<Draggable id={1} />
<Draggable id={2} />
<Draggable id={3} />
<Draggable id={4} />
<Draggable id={5} />
</View>
</View>
);
}
}
let CIRCLE_RADIUS = 30;
const styles = StyleSheet.create({
mainContainer: {
flex: 1,
},
ballContainer: {
height: 200,
},
circle: {
backgroundColor: 'skyblue',
width: CIRCLE_RADIUS * 2,
height: CIRCLE_RADIUS * 2,
borderRadius: CIRCLE_RADIUS,
},
row: {
flexDirection: 'row',
},
dropZone: {
height: 200,
backgroundColor: '#00334d',
},
text: {
marginTop: 25,
marginLeft: 5,
marginRight: 5,
textAlign: 'center',
color: '#fff',
fontSize: 25,
fontWeight: 'bold',
},
});