Search code examples
react-nativereact-native-flatlistreact-native-scrollview

Need help: I want to create Drag and Drop in react native


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.


Solution

  • drag and drop is controlled by pangesuter controller for more drag and drop follow that article

    if you want to sense drop in chart you need to customize the graph library that you have provided.