У меня есть задача в реагировать нативно, в которой у меня есть гистограмма с несколькими барами, под диаграммой у нас есть перетаскиваемые элементы, которые мы должны перетаскивать на одну запись гистограммы.
То, что я сделал до сих пор, это
У меня есть плоский список с кратными значениями. Каждый элемент плоского списка имеет область выпадения с гистограммой победителя. У меня есть три события, которые я должен перетащить в плоский список. Я уже пытаюсь использовать Reaction-native-easy-dnd , но это не работает в flatlist. Теперь я пытаюсь использовать PanResponder. но когда я перетаскиваю событие в область перетаскивания, panResponder области перетаскивания не получает жест. Вот пример кода. // Родительский компонент
import React, { Component } from "react";
import { View, StyleSheet, PanResponder, ScrollView } from "react-native";
import DragBall from "./Drag";
import DropArea from "./DropArea";
class Parent extends Component {
constructor(props) {
super(props);
this.state = {
target: null
}
}
render() {
return (
<ScrollView >
<View style={styles.container}>
<View style={{ flexDirection: "row" }}>
<DropArea color="grey" />
<DropArea color="blue" />
<DropArea color="green" />
</View>
<View style={styles.dragContainer}>
<DragBall value="1" target={this.state.target} />
<DragBall value="2" target={this.state.target} />
<DragBall value="3" target={this.state.target} />
<DragBall value="4" target={this.state.target} />
</View>
</View>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#f2f2f2",
height: "100%"
},
dropContainer: {
flex: 1,
borderBottomWidth: 2,
borderBottomColor: "black"
},
dragContainer: {
flex: 1,
backgroundColor: "red",
alignItems: "center",
justifyContent: "space-around",
flexDirection: "row",
height: 400
}
});
export default Parent;
// Перетаскивание событий
import React, { Component } from "react";
import { View, Text, PanResponder, Animated, StyleSheet } from "react-native";
class Check extends Component {
constructor(props) {
super(props);
this.state = {
pan: new Animated.ValueXY()
};
this._val = { x: 0, y: 0 };
this.state.pan.addListener(value => (this._val = value));
this._panResponder = PanResponder.create({
onStartShouldSetPanResponder: (e, gesture) => true,
onPanResponderTerminationRequest: () => true,
// onStartShouldSetPanResponderCapture: e => true,
// onPanResponderTerminationRequest: () => true,
onPanResponderTerminate:() => true,
// adjusting delta value
// onResponderTerminationRequest: e => fal,
onStartShouldSetResponderCapture: e => false,
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: (evt, gesture) => {
// console.log("evt target", evt.target, "props target", this.props.target
}
});
}
render() {
const { viewProps } = this.props;
return (
<Animated.View
{...this._panResponder.panHandlers}
style={[
styles.balls,
{ transform: this.state.pan.getTranslateTransform() }
]}
>
<Text style={styles.text}>{this.props.value}</Text>
</Animated.View>
);
}
}
const styles = StyleSheet.create({
balls: {
backgroundColor: "skyblue",
width: 60,
height: 60,
borderRadius: 60,
alignItems: "center",
justifyContent: "center"
},
text: {
textAlign: "center"
}
});
export default Check;
// Область перетаскивания
import React, { Component } from "react";
import { View, StyleSheet, PanResponder } from "react-native";
import DragBall from "./Drag";
class DropArea extends Component {
constructor(props) {
super(props);
// console.log(props)
this._panResponder = PanResponder.create({
onPanResponderGrant: evt => {
console.log("=====Drop Grant=====");
},
onStartShouldSetPanResponder: (e, gesture) => true,
onStartShouldSetPanResponderCapture: () => true,
// onPanResponderTerminate: () => true,
// onPanResponderTerminationRequest: () => true,
onMoveShouldSetPanResponder: evt => {
console.log("Droooooooooooooooooooop");
return true;
},
onMoveShouldSetPanResponderCapture: (e, gesture) => {
console.log("capture gesture");
},
onResponderReject: evt => {
console.log("Reject=====");
},
// onPanResponderMove: evt => {
// console.log("truuuuuuuuuue");
// },
onPanResponderRelease: (evt, gesture) => {
console.log("===release===");
}
});
}
// handleViewMove = event => {
// console.log("===================");
// return true;
// };
render() {
return (
<View
style={styles(this.props).dropContainer}
{...this._panResponder.panHandlers}
></View>
);
}
}
const styles = props =>
StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#f2f2f2"
},
dropContainer: {
flex: 1,
borderBottomWidth: 2,
borderBottomColor: "black",
backgroundColor: props.color,
height: 300
},
dragContainer: {
flex: 1,
width: 30,
backgroundColor: "red",
alignItems: "center",
justifyContent: "space-around",
flexDirection: "row"
}
});
export default DropArea;
Приведенный выше код является простым перетаскиванием. с тремя перетаскиваемыми анимированными изображениями и тремя выпадающими областями. Фактическая работа в следующем снимке экрана здесь . На этом изображении перетаскиваемые события - это изображение ребенка и изображение портфеля. который я должен бросить на каждый столбец.