I have a task in react native, in which i have a bar chart with multiple bars, below the chart we have draggable elements, which we are supposed to drag over a single entry of the bar chart.
What i have done so far is,
I have flat-list with multiples values. Each flat-list item have drop area with victory native bar chart. I have three events, which i have to drag and drop on flatlist dropable area. I already try to use react-native-easy-dnd ,but it doesn't work in flatlist. Now i try to use PanResponder. but when i drag event on drop area, the panResponder of drop area didn't get gesture. Here is code sample. //Parent Component
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;
// Drag Events
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;
// Drop Area
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;
The above code is simple drag and drop. with three draggable animated view and three dropable areas. The actual work is in following screen shot here . In this Image draggable events is child picture and briefcase picture. which i have to drop on each barcharts.